Index: /branches/rel3/psLib/.cvsignore
===================================================================
--- /branches/rel3/psLib/.cvsignore	(revision 2163)
+++ /branches/rel3/psLib/.cvsignore	(revision 2163)
@@ -0,0 +1,6 @@
+bin
+lib
+man
+psLib.kdevelop.*
+docs
+testbin
Index: /branches/rel3/psLib/psLib.kdevelop
===================================================================
--- /branches/rel3/psLib/psLib.kdevelop	(revision 2163)
+++ /branches/rel3/psLib/psLib.kdevelop	(revision 2163)
@@ -0,0 +1,165 @@
+<?xml version = '1.0'?>
+<kdevelop>
+  <general>
+    <author>Robert DeSonia</author>
+    <email>robert.desonia@mhpcc.hpc.mil</email>
+    <version>$VERSION$</version>
+    <projectmanagement>KDevCustomProject</projectmanagement>
+    <primarylanguage>C</primarylanguage>
+    <ignoreparts>
+      <part>KDevClassView</part>
+      <part>KDevClearCase</part>
+      <part>KDevFileGroups</part>
+      <part>KDevPerforce</part>
+    </ignoreparts>
+    <projectdirectory>.</projectdirectory>
+    <absoluteprojectpath>false</absoluteprojectpath>
+    <description/>
+    <secondaryLanguages/>
+  </general>
+  <kdevcustomproject>
+    <run>
+      <mainprogram/>
+      <directoryradio>executable</directoryradio>
+      <customdirectory>/</customdirectory>
+      <programargs/>
+      <terminal>false</terminal>
+      <autocompile>true</autocompile>
+      <envvars/>
+    </run>
+    <general>
+      <activedir>src/image</activedir>
+    </general>
+    <build>
+      <buildtool>make</buildtool>
+      <builddir>src</builddir>
+    </build>
+    <make>
+      <abortonerror>false</abortonerror>
+      <numberofjobs>1</numberofjobs>
+      <dontact>false</dontact>
+      <makebin/>
+      <selectedenvironment>default</selectedenvironment>
+      <environments>
+        <default/>
+      </environments>
+    </make>
+  </kdevcustomproject>
+  <kdevdebugger>
+    <general>
+      <dbgshell/>
+      <programargs/>
+      <gdbpath/>
+      <configGdbScript/>
+      <runShellScript/>
+      <runGdbScript/>
+      <breakonloadinglibs>true</breakonloadinglibs>
+      <separatetty>false</separatetty>
+      <floatingtoolbar>false</floatingtoolbar>
+    </general>
+    <display>
+      <staticmembers>false</staticmembers>
+      <demanglenames>true</demanglenames>
+    </display>
+  </kdevdebugger>
+  <kdevdoctreeview>
+    <ignoretocs>
+      <toc>ada</toc>
+      <toc>ada_bugs_gcc</toc>
+      <toc>bash</toc>
+      <toc>bash_bugs</toc>
+      <toc>clanlib</toc>
+      <toc>fortran_bugs_gcc</toc>
+      <toc>gnome1</toc>
+      <toc>gnustep</toc>
+      <toc>gtk</toc>
+      <toc>gtk_bugs</toc>
+      <toc>haskell</toc>
+      <toc>haskell_bugs_ghc</toc>
+      <toc>java_bugs_gcc</toc>
+      <toc>java_bugs_sun</toc>
+      <toc>kde2book</toc>
+      <toc>libstdc++</toc>
+      <toc>opengl</toc>
+      <toc>pascal_bugs_fp</toc>
+      <toc>php</toc>
+      <toc>php_bugs</toc>
+      <toc>perl</toc>
+      <toc>perl_bugs</toc>
+      <toc>python</toc>
+      <toc>python_bugs</toc>
+      <toc>qt-kdev3</toc>
+      <toc>ruby</toc>
+      <toc>ruby_bugs</toc>
+      <toc>sdl</toc>
+      <toc>stl</toc>
+      <toc>sw</toc>
+      <toc>w3c-dom-level2-html</toc>
+      <toc>w3c-svg</toc>
+      <toc>w3c-uaag10</toc>
+      <toc>wxwindows_bugs</toc>
+    </ignoretocs>
+    <ignoreqt_xml>
+      <toc>Guide to the Qt Translation Tools</toc>
+      <toc>Qt Assistant Manual</toc>
+      <toc>Qt Designer Manual</toc>
+      <toc>Qt Reference Documentation</toc>
+      <toc>qmake User Guide</toc>
+    </ignoreqt_xml>
+    <ignoredoxygen>
+      <toc>KDE Libraries (Doxygen)</toc>
+    </ignoredoxygen>
+    <projectdoc>
+      <userdocDir>html/</userdocDir>
+      <apidocDir>html/</apidocDir>
+    </projectdoc>
+    <ignorekdocs/>
+    <ignoredevhelp/>
+  </kdevdoctreeview>
+  <kdevfilecreate>
+    <filetypes/>
+    <useglobaltypes>
+      <type ext="c" />
+      <type ext="h" />
+    </useglobaltypes>
+  </kdevfilecreate>
+  <kdevcppsupport>
+    <references/>
+    <codecompletion>
+      <includeGlobalFunctions>true</includeGlobalFunctions>
+      <includeTypes>true</includeTypes>
+      <includeEnums>true</includeEnums>
+      <includeTypedefs>false</includeTypedefs>
+      <automaticCodeCompletion>true</automaticCodeCompletion>
+      <automaticArgumentsHint>true</automaticArgumentsHint>
+      <automaticHeaderCompletion>true</automaticHeaderCompletion>
+      <codeCompletionDelay>250</codeCompletionDelay>
+      <argumentsHintDelay>400</argumentsHintDelay>
+      <headerCompletionDelay>250</headerCompletionDelay>
+    </codecompletion>
+  </kdevcppsupport>
+  <kdevfileview>
+    <groups>
+      <hidenonprojectfiles>false</hidenonprojectfiles>
+      <hidenonlocation>false</hidenonlocation>
+    </groups>
+    <tree>
+      <hidepatterns>*.o,*.lo,CVS</hidepatterns>
+      <hidenonprojectfiles>false</hidenonprojectfiles>
+      <showvcsfields>true</showvcsfields>
+    </tree>
+  </kdevfileview>
+  <cppsupportpart>
+    <filetemplates>
+      <interfacesuffix>.h</interfacesuffix>
+      <implementationsuffix>.cpp</implementationsuffix>
+    </filetemplates>
+  </cppsupportpart>
+  <kdevcvsservice>
+    <recursivewhenupdate>true</recursivewhenupdate>
+    <prunedirswhenupdate>true</prunedirswhenupdate>
+    <createdirswhenupdate>true</createdirswhenupdate>
+    <recursivewhencommitremove>true</recursivewhencommitremove>
+    <revertoptions>-C</revertoptions>
+  </kdevcvsservice>
+</kdevelop>
Index: /branches/rel3/psLib/psLib.kdevelop.filelist
===================================================================
--- /branches/rel3/psLib/psLib.kdevelop.filelist	(revision 2163)
+++ /branches/rel3/psLib/psLib.kdevelop.filelist	(revision 2163)
@@ -0,0 +1,451 @@
+# KDevelop Custom Project File List
+psLib.kdevelop
+psLib.kdevses
+testbin/CVS/Entries
+testbin/CVS/Repository
+testbin/CVS/Root
+test/FullUnitTest
+test/Makefile
+test/psTest.c
+test/psTest.h
+test/runTest
+test/tst_template.c
+test/sysUtils/Makefile
+test/sysUtils/tst_psAbort.c
+test/sysUtils/tst_psError.c
+test/sysUtils/tst_psLogMsg.c
+test/sysUtils/tst_psMemory.c
+test/sysUtils/tst_psStringCopy.c
+test/sysUtils/tst_psTrace.c
+test/sysUtils/verified/tst_psAbort.stderr
+test/sysUtils/verified/tst_psAbort.stdout
+test/sysUtils/verified/tst_psError.stderr
+test/sysUtils/verified/tst_psError.stdout
+test/sysUtils/verified/tst_psHash00.stderr
+test/sysUtils/verified/tst_psHash00.stdout
+test/sysUtils/verified/tst_psHash01.stderr
+test/sysUtils/verified/tst_psHash01.stdout
+test/sysUtils/verified/tst_psHash02.stderr
+test/sysUtils/verified/tst_psHash03.stderr
+test/sysUtils/verified/tst_psHash03.stdout
+test/sysUtils/verified/tst_psHash04.stderr
+test/sysUtils/verified/tst_psHash04.stdout
+test/sysUtils/verified/tst_psLogMsg.stderr
+test/sysUtils/verified/tst_psLogMsg.stdout
+test/sysUtils/verified/tst_psMemory.stderr
+test/sysUtils/verified/tst_psStringCopy.stderr
+test/sysUtils/verified/tst_psStringCopy.stdout
+test/sysUtils/verified/tst_psTrace.stderr
+test/sysUtils/verified/tst_psTrace.stdout
+test/sysUtils/verified/CVS/Entries
+test/sysUtils/verified/CVS/Repository
+test/sysUtils/verified/CVS/Root
+test/sysUtils/CVS/Entries
+test/sysUtils/CVS/Entries.Log
+test/sysUtils/CVS/Repository
+test/sysUtils/CVS/Root
+test/sysUtils/builddir/CVS/Entries
+test/sysUtils/builddir/CVS/Repository
+test/sysUtils/builddir/CVS/Root
+test/image/Makefile
+test/image/tst_psImage.c
+test/image/tst_psImageExtraction.c
+test/image/tst_psImageFFT.c
+test/image/tst_psImageIO.c
+test/image/tst_psImageManip.c
+test/image/tst_psImageStats00.c
+test/image/tst_psImageStats01.c
+test/image/tst_psImageStats02.c
+test/image/tst_psImageStats03.c
+test/image/verified/fOut.fits
+test/image/verified/sOut.fits
+test/image/verified/tst_psImage.stderr
+test/image/verified/tst_psImageExtraction.stderr
+test/image/verified/tst_psImageFFT.stderr
+test/image/verified/tst_psImageIO.stderr
+test/image/verified/tst_psImageManip.stderr
+test/image/verified/tst_psImageManip.stdout
+test/image/verified/tst_psImageStats00.stderr
+test/image/verified/tst_psImageStats00.stdout
+test/image/verified/tst_psImageStats01.stderr
+test/image/verified/tst_psImageStats01.stdout
+test/image/verified/tst_psImageStats02.stdout
+test/image/verified/CVS/Entries
+test/image/verified/CVS/Repository
+test/image/verified/CVS/Root
+test/image/CVS/Entries
+test/image/CVS/Entries.Log
+test/image/CVS/Repository
+test/image/CVS/Root
+test/dataManip/Makefile
+test/dataManip/tst_psFunc00.c
+test/dataManip/tst_psFunc01.c
+test/dataManip/tst_psFunc02.c
+test/dataManip/tst_psFunc03.c
+test/dataManip/tst_psFunc04.c
+test/dataManip/tst_psFunc05.c
+test/dataManip/tst_psFunc07.c
+test/dataManip/tst_psHist00.c
+test/dataManip/tst_psHist01.c
+test/dataManip/tst_psHist02.c
+test/dataManip/tst_psHist03.c
+test/dataManip/tst_psMatrix01.c
+test/dataManip/tst_psMatrix02.c
+test/dataManip/tst_psMatrix03.c
+test/dataManip/tst_psMatrix04.c
+test/dataManip/tst_psMatrix05.c
+test/dataManip/tst_psMatrix06.c
+test/dataManip/tst_psMatrix07.c
+test/dataManip/tst_psMatrixVectorArithmetic01.c
+test/dataManip/tst_psMatrixVectorArithmetic02.c
+test/dataManip/tst_psMatrixVectorArithmetic03.c
+test/dataManip/tst_psMinimize00.c
+test/dataManip/tst_psMinimize01.c
+test/dataManip/tst_psMinimize02.c
+test/dataManip/tst_psMinimize03.c
+test/dataManip/tst_psMinimize04.c
+test/dataManip/tst_psMinimize05.c
+test/dataManip/tst_psMinimize06.c
+test/dataManip/tst_psStats00.c
+test/dataManip/tst_psStats01.c
+test/dataManip/tst_psStats02.c
+test/dataManip/tst_psStats03.c
+test/dataManip/tst_psStats04.c
+test/dataManip/tst_psStats05.c
+test/dataManip/tst_psStats06.c
+test/dataManip/tst_psStats07.c
+test/dataManip/tst_psStats08.c
+test/dataManip/tst_psStats09.c
+test/dataManip/tst_psVectorFFT.c
+test/dataManip/verified/tst_psFunc00.stderr
+test/dataManip/verified/tst_psFunc00.stdout
+test/dataManip/verified/tst_psFunc01.stdout
+test/dataManip/verified/tst_psHist00.stdout
+test/dataManip/verified/tst_psHist01.stdout
+test/dataManip/verified/tst_psHist02.stdout
+test/dataManip/verified/tst_psMatrix01.stdout
+test/dataManip/verified/tst_psMatrix02.stderr
+test/dataManip/verified/tst_psMatrix02.stdout
+test/dataManip/verified/tst_psMatrix03.stderr
+test/dataManip/verified/tst_psMatrix03.stdout
+test/dataManip/verified/tst_psMatrix04.stderr
+test/dataManip/verified/tst_psMatrix04.stdout
+test/dataManip/verified/tst_psMatrix05.stdout
+test/dataManip/verified/tst_psMatrix06.stdout
+test/dataManip/verified/tst_psMatrix07.stderr
+test/dataManip/verified/tst_psMatrix07.stdout
+test/dataManip/verified/tst_psMatrixVectorArithmetic01.stderr
+test/dataManip/verified/tst_psMatrixVectorArithmetic01.stdout
+test/dataManip/verified/tst_psMatrixVectorArithmetic02.stdout
+test/dataManip/verified/tst_psMatrixVectorArithmetic03.stderr
+test/dataManip/verified/tst_psMatrixVectorArithmetic03.stdout
+test/dataManip/verified/tst_psStats00.stdout
+test/dataManip/verified/tst_psStats01.stdout
+test/dataManip/verified/tst_psStats02.stdout
+test/dataManip/verified/tst_psStats03.stdout
+test/dataManip/verified/tst_psStats05.stdout
+test/dataManip/verified/tst_psStats06.stdout
+test/dataManip/verified/tst_psStats07.stdout
+test/dataManip/verified/tst_psStats08.stdout
+test/dataManip/verified/tst_psStats09.stdout
+test/dataManip/verified/tst_psVectorFFT.stderr
+test/dataManip/verified/CVS/Entries
+test/dataManip/verified/CVS/Repository
+test/dataManip/verified/CVS/Root
+test/dataManip/CVS/Entries
+test/dataManip/CVS/Entries.Log
+test/dataManip/CVS/Repository
+test/dataManip/CVS/Root
+test/dataManip/builddir/CVS/Entries
+test/dataManip/builddir/CVS/Repository
+test/dataManip/builddir/CVS/Root
+test/CVS/Entries
+test/CVS/Entries.Log
+test/CVS/Repository
+test/CVS/Root
+test/collections/Makefile
+test/collections/tst_psArray.c
+test/collections/tst_psBitSet.c
+test/collections/tst_psHash00.c
+test/collections/tst_psHash01.c
+test/collections/tst_psHash02.c
+test/collections/tst_psHash03.c
+test/collections/tst_psHash04.c
+test/collections/tst_psList.c
+test/collections/tst_psVector.c
+test/collections/tst_psVectorSort_01.c
+test/collections/tst_psVectorSort_02.c
+test/collections/tst_psVectorSort_03.c
+test/collections/tst_psVectorSort_04.c
+test/collections/verified/tst_psArray.stdout
+test/collections/verified/tst_psBitSet.stderr
+test/collections/verified/tst_psHash00.stderr
+test/collections/verified/tst_psHash00.stdout
+test/collections/verified/tst_psHash01.stderr
+test/collections/verified/tst_psHash01.stdout
+test/collections/verified/tst_psHash02.stderr
+test/collections/verified/tst_psHash03.stderr
+test/collections/verified/tst_psHash03.stdout
+test/collections/verified/tst_psHash04.stderr
+test/collections/verified/tst_psHash04.stdout
+test/collections/verified/tst_psList.stderr
+test/collections/verified/tst_psSort_01.stderr
+test/collections/verified/tst_psSort_01.stdout
+test/collections/verified/tst_psSort_02.stdout
+test/collections/verified/tst_psSort_03.stderr
+test/collections/verified/tst_psSort_03.stdout
+test/collections/verified/tst_psSort_04.stderr
+test/collections/verified/tst_psSort_04.stdout
+test/collections/verified/tst_psVector.stderr
+test/collections/verified/tst_psVector.stdout
+test/collections/verified/tst_psVector_01.stderr
+test/collections/verified/tst_psVector_01.stdout
+test/collections/verified/tst_psVector_02.stdout
+test/collections/verified/tst_psVector_03.stdout
+test/collections/verified/tst_psVectorSort_01.stderr
+test/collections/verified/tst_psVectorSort_01.stdout
+test/collections/verified/tst_psVectorSort_02.stderr
+test/collections/verified/tst_psVectorSort_02.stdout
+test/collections/verified/tst_psVectorSort_03.stderr
+test/collections/verified/tst_psVectorSort_03.stdout
+test/collections/verified/tst_psVectorSort_04.stderr
+test/collections/verified/tst_psVectorSort_04.stdout
+test/collections/verified/CVS/Entries
+test/collections/verified/CVS/Repository
+test/collections/verified/CVS/Root
+test/collections/CVS/Entries
+test/collections/CVS/Entries.Log
+test/collections/CVS/Repository
+test/collections/CVS/Root
+test/collections/builddir/CVS/Entries
+test/collections/builddir/CVS/Repository
+test/collections/builddir/CVS/Root
+test/astronomy/header_1.fits
+test/astronomy/header_2.fits
+test/astronomy/Makefile
+test/astronomy/tst_psMetadata_01.c
+test/astronomy/tst_psMetadata_02.c
+test/astronomy/tst_psMetadata_03.c
+test/astronomy/tst_psMetadata_04.c
+test/astronomy/tst_psMetadata_05.c
+test/astronomy/tst_psMetadata_06.c
+test/astronomy/tst_psTime_01.c
+test/astronomy/tst_psTime_02.c
+test/astronomy/verified/tst_psMetadata_01.stderr
+test/astronomy/verified/tst_psMetadata_01.stdout
+test/astronomy/verified/tst_psMetadata_02.stderr
+test/astronomy/verified/tst_psMetadata_02.stdout
+test/astronomy/verified/tst_psMetadata_03.stderr
+test/astronomy/verified/tst_psMetadata_03.stdout
+test/astronomy/verified/tst_psMetadata_04.stderr
+test/astronomy/verified/tst_psMetadata_04.stdout
+test/astronomy/verified/tst_psMetadata_05.stderr
+test/astronomy/verified/tst_psMetadata_05.stdout
+test/astronomy/verified/tst_psMetadata_06.stdout
+test/astronomy/verified/tst_psTime_01.stdout
+test/astronomy/verified/tst_psTime_02.stderr
+test/astronomy/verified/tst_psTime_02.stdout
+test/astronomy/verified/CVS/Entries
+test/astronomy/verified/CVS/Repository
+test/astronomy/verified/CVS/Root
+test/astronomy/CVS/Entries
+test/astronomy/CVS/Entries.Log
+test/astronomy/CVS/Repository
+test/astronomy/CVS/Root
+test/astronomy/builddir/tst_psMetadata_01.d
+test/astronomy/builddir/tst_psMetadata_02.d
+test/astronomy/builddir/tst_psMetadata_03.d
+test/astronomy/builddir/tst_psMetadata_04.d
+test/astronomy/builddir/tst_psMetadata_05.d
+test/astronomy/builddir/tst_psMetadata_06.d
+test/astronomy/builddir/tst_psTime_01.d
+test/astronomy/builddir/tst_psTime_02.d
+test/astronomy/builddir/CVS/Entries
+test/astronomy/builddir/CVS/Repository
+test/astronomy/builddir/CVS/Root
+src/Doxyfile
+src/mainpage.dox
+src/Makefile
+src/Makefile.Globals
+src/parseErrorCodes.pl
+src/psErrorCodes.dat
+src/pslib.h
+src/sysUtils/Makefile
+src/sysUtils/psAbort.c
+src/sysUtils/psAbort.h
+src/sysUtils/psError.c
+src/sysUtils/psError.h
+src/sysUtils/psErrorCodes.c
+src/sysUtils/psErrorCodes.h
+src/sysUtils/psLogMsg.c
+src/sysUtils/psLogMsg.h
+src/sysUtils/psMemory.c
+src/sysUtils/psMemory.h
+src/sysUtils/psString.c
+src/sysUtils/psString.h
+src/sysUtils/psSysUtilsErrors.dat
+src/sysUtils/psSysUtilsErrors.h
+src/sysUtils/psTrace.c
+src/sysUtils/psTrace.h
+src/sysUtils/psType.h
+src/sysUtils/README
+src/sysUtils/makedir/psAbort.d
+src/sysUtils/makedir/psError.d
+src/sysUtils/makedir/psErrorCodes.d
+src/sysUtils/makedir/psHash.d
+src/sysUtils/makedir/psLogMsg.d
+src/sysUtils/makedir/psMemory.d
+src/sysUtils/makedir/psString.d
+src/sysUtils/makedir/psTrace.d
+src/sysUtils/makedir/CVS/Entries
+src/sysUtils/makedir/CVS/Repository
+src/sysUtils/makedir/CVS/Root
+src/sysUtils/CVS/Entries
+src/sysUtils/CVS/Entries.Log
+src/sysUtils/CVS/Repository
+src/sysUtils/CVS/Root
+src/image/Makefile
+src/image/psImage.c
+src/image/psImage.h
+src/image/psImageConvolve.c
+src/image/psImageConvolve.h
+src/image/psImageErrors.dat
+src/image/psImageErrors.h
+src/image/psImageExtraction.c
+src/image/psImageExtraction.h
+src/image/psImageFFT.c
+src/image/psImageFFT.h
+src/image/psImageIO.c
+src/image/psImageIO.h
+src/image/psImageManip.c
+src/image/psImageManip.h
+src/image/psImageStats.c
+src/image/psImageStats.h
+src/image/makedir/psImage.d
+src/image/makedir/psImageConvolve.d
+src/image/makedir/psImageExtraction.d
+src/image/makedir/psImageFFT.d
+src/image/makedir/psImageIO.d
+src/image/makedir/psImageManip.d
+src/image/makedir/psImageStats.d
+src/image/makedir/CVS/Entries
+src/image/makedir/CVS/Repository
+src/image/makedir/CVS/Root
+src/image/CVS/Entries
+src/image/CVS/Entries.Log
+src/image/CVS/Repository
+src/image/CVS/Root
+src/dataManip/Makefile
+src/dataManip/psDataManipErrors.dat
+src/dataManip/psDataManipErrors.h
+src/dataManip/psFunctions.c
+src/dataManip/psFunctions.h
+src/dataManip/psMatrix.c
+src/dataManip/psMatrix.h
+src/dataManip/psMatrixVectorArithmetic.c
+src/dataManip/psMatrixVectorArithmetic.h
+src/dataManip/psMinimize.c
+src/dataManip/psMinimize.h
+src/dataManip/psStats.c
+src/dataManip/psStats.h
+src/dataManip/psVectorFFT.c
+src/dataManip/psVectorFFT.h
+src/dataManip/makedir/psFunctions.d
+src/dataManip/makedir/psMatrix.d
+src/dataManip/makedir/psMatrixVectorArithmetic.d
+src/dataManip/makedir/psMinimize.d
+src/dataManip/makedir/psStats.d
+src/dataManip/makedir/psVectorFFT.d
+src/dataManip/makedir/CVS/Entries
+src/dataManip/makedir/CVS/Repository
+src/dataManip/makedir/CVS/Root
+src/dataManip/CVS/Entries
+src/dataManip/CVS/Entries.Log
+src/dataManip/CVS/Repository
+src/dataManip/CVS/Root
+src/CVS/Entries
+src/CVS/Entries.Log
+src/CVS/Repository
+src/CVS/Root
+src/collections/Makefile
+src/collections/psArray.c
+src/collections/psArray.h
+src/collections/psBitSet.c
+src/collections/psBitSet.h
+src/collections/psCollectionsErrors.dat
+src/collections/psCollectionsErrors.h
+src/collections/psCompare.c
+src/collections/psCompare.h
+src/collections/psHash.c
+src/collections/psHash.h
+src/collections/psList.c
+src/collections/psList.h
+src/collections/psScalar.c
+src/collections/psScalar.h
+src/collections/psVector.c
+src/collections/psVector.h
+src/collections/makedir/psArray.d
+src/collections/makedir/psBitSet.d
+src/collections/makedir/psCompare.d
+src/collections/makedir/psHash.d
+src/collections/makedir/psList.d
+src/collections/makedir/psScalar.d
+src/collections/makedir/psVector.d
+src/collections/makedir/CVS/Entries
+src/collections/makedir/CVS/Repository
+src/collections/makedir/CVS/Root
+src/collections/CVS/Entries
+src/collections/CVS/Entries.Log
+src/collections/CVS/Repository
+src/collections/CVS/Root
+src/astronomy/Makefile
+src/astronomy/psAstrometry.c
+src/astronomy/psAstrometry.h
+src/astronomy/psAstronomyErrors.dat
+src/astronomy/psAstronomyErrors.h
+src/astronomy/psCoord.c
+src/astronomy/psCoord.h
+src/astronomy/psMetadata.c
+src/astronomy/psMetadata.h
+src/astronomy/psPhotometry.h
+src/astronomy/psTime.c
+src/astronomy/psTime.h
+src/astronomy/slalib.h
+src/astronomy/makedir/psAstrometry.d
+src/astronomy/makedir/psCoord.d
+src/astronomy/makedir/psMetadata.d
+src/astronomy/makedir/psTime.d
+src/astronomy/makedir/CVS/Entries
+src/astronomy/makedir/CVS/Repository
+src/astronomy/makedir/CVS/Root
+src/astronomy/depend/CVS/Entries
+src/astronomy/depend/CVS/Repository
+src/astronomy/depend/CVS/Root
+src/astronomy/CVS/Entries
+src/astronomy/CVS/Entries.Log
+src/astronomy/CVS/Repository
+src/astronomy/CVS/Root
+lib/CVS/Entries
+lib/CVS/Repository
+lib/CVS/Root
+include/CVS/Entries
+include/CVS/Repository
+include/CVS/Root
+data/eopc01.1900-2004
+data/finals.all
+data/readme.eopc01
+data/readme.finals
+data/readme.ser7
+data/readme.tai-utc
+data/ser7.dat
+data/tai-utc.dat
+data/CVS/Entries
+data/CVS/Repository
+data/CVS/Root
+CVS/Entries
+CVS/Entries.Log
+CVS/Repository
+CVS/Root
+test/image/tst_psImageConvolve.c
+test/astronomy/tst_psAstrometry.c
+test/astronomy/tst_psMetadataIO.c
Index: /branches/rel3/psLib/psLib.kdevses
===================================================================
--- /branches/rel3/psLib/psLib.kdevses	(revision 2163)
+++ /branches/rel3/psLib/psLib.kdevses	(revision 2163)
@@ -0,0 +1,48 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE KDevPrjSession>
+<KDevPrjSession>
+ <DocsAndViews NumberOfDocuments="3" >
+  <Doc0 NumberOfViews="1" URL="file:/home/desonia/psLib/src/Doxyfile" >
+   <View0 line="27" Type="???" >
+    <AdditionalSettings Top="2" Width="1212" Attach="1" Height="1027" Left="2" MinMaxMode="0" />
+   </View0>
+  </Doc0>
+  <Doc1 NumberOfViews="1" URL="file:/home/desonia/psLib/src/image/psImageExtraction.c" >
+   <View0 line="311" Type="???" >
+    <AdditionalSettings Top="2" Width="1212" Attach="1" Height="752" Left="2" MinMaxMode="0" />
+   </View0>
+  </Doc1>
+  <Doc2 NumberOfViews="1" URL="file:/home/desonia/psLib/src/image/psImageErrors.dat" >
+   <View0 line="21" Type="???" >
+    <AdditionalSettings Top="2" Width="1212" Attach="1" Height="1001" Left="2" MinMaxMode="0" />
+   </View0>
+  </Doc2>
+ </DocsAndViews>
+ <pluginList>
+  <kdevbookmarks>
+   <bookmarks>
+    <bookmark url="/home/desonia/psLib/test/dataManip/tst_psImageManip.c" >
+     <mark line="615" />
+     <mark line="652" />
+     <mark line="593" />
+    </bookmark>
+    <bookmark url="/home/desonia/psLib/src/dataManip/psMatrixVectorArithmetic.c" >
+     <mark line="60" />
+    </bookmark>
+    <bookmark url="/home/desonia/psLib/src/collections/psBitSet.c" >
+     <mark line="194" />
+    </bookmark>
+   </bookmarks>
+  </kdevbookmarks>
+  <kdevsubversion>
+   <subversion recurseresolve="1" recurserelocate="1" recursemerge="1" recursecommit="1" base="" recursepropget="1" recurseswitch="1" recurseupdate="1" recursepropset="1" recursediff="1" recurserevert="1" forcemove="1" recursecheckout="1" forceremove="1" recurseadd="1" recurseproplist="1" forcemerge="1" />
+  </kdevsubversion>
+  <kdevvalgrind>
+   <executable path="" params="" />
+   <valgrind path="" params="" />
+  </kdevvalgrind>
+  <kdevdebugger>
+   <breakpointList/>
+  </kdevdebugger>
+ </pluginList>
+</KDevPrjSession>
Index: /branches/rel3/psLib/src/.cvsignore
===================================================================
--- /branches/rel3/psLib/src/.cvsignore	(revision 2163)
+++ /branches/rel3/psLib/src/.cvsignore	(revision 2163)
@@ -0,0 +1,1 @@
+DoxygenLog
Index: /branches/rel3/psLib/src/Doxyfile
===================================================================
--- /branches/rel3/psLib/src/Doxyfile	(revision 2163)
+++ /branches/rel3/psLib/src/Doxyfile	(revision 2163)
@@ -0,0 +1,1085 @@
+# Doxyfile 1.3.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "Pan-STARRS Foundation Library"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER         = V1.2-R3
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = ../docs
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch,
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en
+# (Japanese with English messages), Korean, Norwegian, Polish, Portuguese,
+# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC    = YES
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
+# members of a class in the documentation of that class as if those members were
+# ordinary class members. Constructors, destructors and assignment operators of
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH        =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explict @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP         = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# reimplements.
+
+INHERIT_DOCS           = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING            = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = DoxygenLog
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = pslib.h \
+                         mainpage.dox \
+                         sysUtils \
+                         image \
+                         dataManip \
+                         collections \
+                         astronomy
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
+# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc
+
+FILE_PATTERNS          = *.h *.dox
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories 
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories.
+
+EXCLUDE_PATTERNS       = *_wrap.c
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.
+
+INPUT_FILTER           = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output dir.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = YES
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 10
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = YES
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = times
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimised for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assigments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = YES
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED             = DOXYGEN
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse the 
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off. Note that this 
+# option is superceded by the HAVE_DOT option below. This is only a fallback. It is 
+# recommended to install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similiar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes that 
+# lay further from the root node will be omitted. Note that setting this option to 
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also 
+# note that a graph may be further truncated if the graph's image dimensions are 
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). 
+# If 0 is used for the depth value (the default), the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
+
Index: /branches/rel3/psLib/src/Makefile
===================================================================
--- /branches/rel3/psLib/src/Makefile	(revision 2163)
+++ /branches/rel3/psLib/src/Makefile	(revision 2163)
@@ -0,0 +1,215 @@
+###############################################################################
+##
+##  Makefile:  psLib
+##
+##  $Revision: 1.17 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-07-29 21:55:44 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+##
+###############################################################################
+
+# Define variable prefix to the top level project - psLib
+# This is necessary for definition in Makefile.Globals
+
+ifndef prefix
+    export prefix=$(shell cd ..;pwd)
+endif
+
+# Include the make global definitions for the project
+
+include Makefile.Globals
+
+# Detect and save the CVS for this makefile
+
+NAME:= "$Name: not supported by cvs2svn $ "
+ifeq ($(NAME), "ame:  $ ")
+   VERSION:= ": Project Version: Unknown "
+else
+   VERSION:= ": Project Version: $(NAME) "
+endif
+
+# Define the target to build
+
+ALLTARGETS = sysUtils collections image dataManip astronomy
+
+TARGET_DYNAMIC = libpslib.$(DLL)
+TARGET_STATIC = libpslib.a
+
+# Define the installation targets
+
+INSTALLTARGETS = installSysUtils installCollections installImage installDataManip installAstronomy
+
+# Define the clean up targets
+
+CLEANTARGETS = cleanSysUtils cleanCollections cleanImage cleanDataManip cleanAstronomy
+
+CLEANDEPTARGETS = cleandepSysUtils cleandepCollections cleandepImage cleandepDataManip cleandepAstronomy
+
+# Define the distribution clean up targets
+
+DISTCLEANTARGETS = distcleanSysUtils distcleanCollections distcleanImage distcleanDataManip distcleanAstronomy
+
+# Define PHONY target "all" which will make all necessary items
+
+all:	$(ALLTARGETS)
+	$(BUILD_DYNAMIC1) $(TARGET_STATIC) $(BUILD_DYNAMIC2) $(TARGET_DYNAMIC)
+	@echo ""
+	@echo "    ---- All targets built successfully $(VERSION) ----"
+	@echo ""
+
+# Define PHONY target "sysUtils" which will make the system utilites
+# portion of the psLib
+
+sysUtils:
+	$(MAKE) --directory=sysUtils all
+
+image:
+	$(MAKE) --directory=image all
+
+collections:
+	$(MAKE) --directory=collections all
+
+dataManip:
+	$(MAKE) --directory=dataManip all
+
+astronomy:
+	$(MAKE) --directory=astronomy all
+
+## ADD ADDITIONAL PORTIONS OF PSLIB HERE
+
+# Define PHONY target "installSysUtils" which will install all the necessary
+# files for system utilities portion of psLib
+
+installSysUtils:
+	$(MAKE) --directory=sysUtils install
+
+installImage:
+	$(MAKE) --directory=image install
+
+installCollections:
+	$(MAKE) --directory=collections install
+
+installDataManip:
+	$(MAKE) --directory=dataManip install
+
+installAstronomy:
+	$(MAKE) --directory=astronomy install
+
+# Define PHONY target "cleanSysUtils" which will clean up the development
+# area for system utilites
+
+cleanSysUtils:
+	$(MAKE) --directory=sysUtils clean
+
+cleanImage:
+	$(MAKE) --directory=image clean
+
+cleanCollections:
+	$(MAKE) --directory=collections clean
+
+cleanDataManip:
+	$(MAKE) --directory=dataManip clean
+
+cleanAstronomy:
+	$(MAKE) --directory=astronomy clean
+
+#Define PHONY target "cleandep*" which will clean up the dependency files
+
+cleandepSysUtils:
+	$(MAKE) --directory=sysUtils cleandep
+
+cleandepImage:
+	$(MAKE) --directory=image cleandep
+
+cleandepCollections:
+	$(MAKE) --directory=collections cleandep
+
+cleandepDataManip:
+	$(MAKE) --directory=dataManip cleandep
+
+cleandepAstronomy:
+	$(MAKE) --directory=astronomy cleandep
+
+# Define PHONY target "distcleanSysUtils which will clean up the distribution
+# files related to system utilities
+
+distcleanSysUtils:
+	$(MAKE) --directory=sysUtils distclean
+        
+distcleanImage:
+	$(MAKE) --directory=image distclean
+        
+distcleanCollections:
+	$(MAKE) --directory=collections distclean
+
+distcleanDataManip:
+	$(MAKE) --directory=dataManip distclean
+
+distcleanAstronomy:
+	$(MAKE) --directory=astronomy distclean
+
+
+# Rule to make include directory if needed
+
+$(includedir):
+	mkdir -p $(includedir)
+
+# Rule to make bin directory if needed
+
+$(bindir):
+	mkdir -p $(bindir)
+
+# Rule to make lib directory if needed
+
+$(libexecdir):
+	mkdir -p $(libexecdir)
+
+# Rule to make man directory if needed
+       
+$(mandir): 
+	mkdir -p $(mandir)
+        
+$(mandir)/man3: $(mandir)
+	mkdir -p $(mandir)/man3
+
+# Rule to make the installation directories if needed
+
+installdirs: $(includedir) $(bindir) $(libexecdir) $(mandir)
+
+# Define PHONY target "install" to make the necessary directories for
+# the installation
+
+install: all installdirs $(INSTALLTARGETS)
+	install *.h $(includedir)
+	install $(TARGET_STATIC) $(libexecdir)
+	install $(TARGET_DYNAMIC) $(libexecdir)
+
+# Define PHONY target "clean" to clean up the development areas for
+# psLib
+
+clean: $(CLEANTARGETS)
+	$(RM) -f $(TARGET_STATIC)
+	$(RM) -f $(TARGET_DYNAMIC)
+
+cleandep: $(CLEANDEPTARGETS)
+
+# Define PHONY target "distclean" to clean up the distribution area for
+# psLib
+
+distclean: $(DISTCLEANTARGETS)
+	$(RM) -f $(libexecdir)/$(TARGET_STATIC)
+	$(RM) -f $(libexecdir)/$(TARGET_DYNAMIC)
+	$(RM) -f $(TARGET_DYNAMIC)
+	$(RM) -f $(TARGET_STATIC)
+
+# Define PHONY target "docs" to generate the Doxygen files for psLib
+        
+docs:
+	$(DOCS)
+
+tags:	
+	cd $(IPPROOT) ; etags `find . \( -name \*.[chy] -o -name \*.cpp \) -print`
+
+# List of PHONY targets with make file
+.PHONY:  sysUtils collections image dataManip astronomy
Index: /branches/rel3/psLib/src/Makefile.Globals
===================================================================
--- /branches/rel3/psLib/src/Makefile.Globals	(revision 2163)
+++ /branches/rel3/psLib/src/Makefile.Globals	(revision 2163)
@@ -0,0 +1,108 @@
+################################################################################
+##
+##  Makefile:  Globals
+##
+##  Assumptions:    Variable "prefix" already defined
+##
+##  $Revision: 1.20 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-10-15 19:10:50 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+##
+###############################################################################
+
+# Determine the operating system and set variable for later conditional use
+
+ifndef OSTYPE
+    OSTYPE = $(shell uname -s)
+endif
+
+# Set environment variables for the project's directory structure
+
+ifndef mandir
+    export mandir = $(prefix)/man
+endif
+
+ifndef includedir
+    export includedir = $(prefix)/include
+endif
+
+ifndef testbindir
+    export testbindir = $(prefix)/testbin
+endif
+
+ifndef bindir
+    export bindir = $(prefix)/bin
+endif
+
+ifndef libexecdir
+    export libexecdir = $(prefix)/lib
+endif
+
+ifndef SER7_FILE
+    export SER7_FILE = $(prefix)/data/ser7.dat
+endif
+
+ifndef TAIUTC_FILE
+    export TAIUTC_FILE = $(prefix)/data/tai-utc.dat
+endif
+
+ifndef sladir
+	export sladir =  /usr/local/star
+endif	
+
+# Set initial value for CFLAGS which will include all OS common flags for GCC
+GCOVFLAGS :=
+CFLAGS := -O0 -g2 -Wall -Werror -std=c99 -D_GNU_SOURCE -pipe $(GCOVFLAGS)
+
+ifdef NO_TRACE
+CFLAGS := $(CFLAGS) -DPS_NO_TRACE=1
+endif
+ 
+# Set initial value for LDFLAGS which will include all OS common flags for GCC and required libraries.
+
+SLA_LINK := $(shell $(sladir)/bin/sla_link)
+EXTLIBS := -lcfitsio -lgsl -lgslcblas -lfftw3f -L$(sladir)/lib $(SLA_LINK) 
+LDFLAGS := -g2 -pipe $(EXTLIBS) 
+
+# Define or refine variables for the Linux OS
+
+ifneq "$(findstring inux,$(OSTYPE))" ""
+    CFLAGS_RELOC := $(CFLAGS) -fpic
+    LDFLAGS_SO := $(LDFLAGS) -fpic -shared -ldl
+    LDFLAGS_DLL := $(LDFLAGS) -fpic -shared
+    DLL = so
+    SO  = so
+    DOCS = doxygen Doxyfile
+    BUILD_DYNAMIC1 = $(CC) $(LDFLAGS_DLL) -Wl,--whole-archive
+    BUILD_DYNAMIC2 = -Wl,--no-whole-archive -lm -o
+endif
+
+ifneq "$(findstring arwin,$(OSTYPE))" ""
+    CFLAGS += -Wno-long-double -DDARWIN 
+    CFLAGS_RELOC := $(CFLAGS)
+    LDFLAGS := $(LDFLAGS) -lmx
+    LDFLAGS_SO := $(LDFLAGS) -bundle -flat_namespace -undefined suppress
+    LDFLAGS_DLL := $(LDFLAGS) -dynamiclib
+    DLL = dylib
+    SO = bundle
+    DOCS =
+    BUILD_DYNAMIC1 = libtool -dynamic
+    BUILD_DYNAMIC2 = -L/usr/local/star/lib -lm -lmx -lgcc $(EXTLIBS) -lg2c -o
+endif
+
+# Set default for variable CC
+
+ifndef CC
+    export CC=cc
+endif
+
+# Set default for variable LD
+
+ifndef LD
+    export LD=ld
+endif
+
+# Set list of PHONY targets
+.PHONY: all install distclean clean docs tags print_header
+
Index: /branches/rel3/psLib/src/astro/psCoord.c
===================================================================
--- /branches/rel3/psLib/src/astro/psCoord.c	(revision 2163)
+++ /branches/rel3/psLib/src/astro/psCoord.c	(revision 2163)
@@ -0,0 +1,470 @@
+/** @file  psCoord.c
+*
+*  @brief Contains basic coordinate transformation definitions and operations
+*
+*  This file defines the basic types for astronomical coordinate
+*  transformation
+*
+*  @ingroup CoordinateTransform
+*
+*  @author George Gusciora, MHPCC
+*
+*  @version $Revision: 1.25 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-14 01:17:50 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include "psType.h"
+#include "psImage.h"
+#include "psArray.h"
+#include "psList.h"
+#include "psCoord.h"
+#include "psMemory.h"
+#include "psAbort.h"
+#include "psTime.h"
+#include "psConstants.h"
+#include "psError.h"
+#include <math.h>
+#include <float.h>
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+#define PS_COT(X) (1.0 / atan(X))
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+static float p_psArg(float x, float y);
+
+/******************************************************************************
+XXX: Verify this arc tan function.
+XXX: macro
+XXX: I don't think this arg() is correct.
+ *****************************************************************************/
+
+float p_psArg(float x,
+              float y)
+{
+    if (y!= 0.0) {
+        return(atan(y/x));
+    } else {
+        return(0.5 * M_PI);
+    }
+    return (0.0);
+    /*
+        if (x > 0) {
+            return (atan(y / x));
+        } else if ((x == 0) && (y == 0)) {
+            return (0.5 * M_PI);
+        } else if ((x == 0) && (y == 0)) {
+            return (-0.5 * M_PI);
+        } else if ((x == 0) && (y == 0)) {
+            return (M_PI + atan(y / x));
+        } else if ((x == 0) && (y == 0)) {
+            return (-M_PI + atan(y / x));
+        }
+        psAbort(__func__, "Unacceptable range for (p_psArg(%f, %f).\n", x, y);
+    */
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+psPlane* psPlaneTransformApply(psPlane* out,
+                               const psPlaneTransform* transform,
+                               const psPlane* coords)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(transform);
+    PS_CHECK_NULL_PTR_RETURN_NULL(coords);
+    if (out == NULL) {
+        out = (psPlane* ) psAlloc(sizeof(psPlane));
+    }
+    out->x = psDPolynomial2DEval(coords->x, coords->y, transform->x);
+    out->y = psDPolynomial2DEval(coords->x, coords->y, transform->y);
+    return (out);
+}
+
+/******************************************************************************
+This transformation takes into account parameters beyond an objects spatial
+coordinates: term3 and term4 (magnitude and color).
+ *****************************************************************************/
+psPlane* psPlaneDistortApply(psPlane* out,
+                             const psPlaneDistort* transform,
+                             const psPlane* coords,
+                             float color,
+                             float magnitude)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(transform);
+    PS_CHECK_NULL_PTR_RETURN_NULL(coords);
+    if (out == NULL) {
+        out = (psPlane* ) psAlloc(sizeof(psPlane));
+    }
+    out->x = psDPolynomial4DEval(coords->x, coords->y, color, magnitude, transform->x);
+    out->y = psDPolynomial4DEval(coords->x, coords->y, color, magnitude, transform->y);
+    return (out);
+}
+
+/******************************************************************************
+This function prototype has been modified since the SDRS.
+ *****************************************************************************/
+psSphereTransform* psSphereTransformAlloc(double NPlat,
+        double Xo,
+        double xo)
+{
+    psSphereTransform* tmp = (psSphereTransform* ) psAlloc(sizeof(psSphereTransform));
+
+    tmp->sinPhi = sin(NPlat);
+    tmp->cosPhi = cos(NPlat);
+    tmp->Xo = Xo;
+    tmp->xo = xo;
+
+    return (tmp);
+}
+
+/******************************************************************************
+This algorithm comes from an email from Gene.  I assume (x,y) corresponds to
+(r,d) in the sphere coordinates.
+ 
+XXX: In Gene's email, there are different variables with similar names (y
+and Y) and in the code, there's cos_y, cos_Y, and cos(y).  Verify that there
+are no typo's.
+ *****************************************************************************/
+psSphere* psSphereTransformApply(psSphere* out,
+                                 const psSphereTransform* transform,
+                                 const psSphere* coord)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(transform);
+    PS_CHECK_NULL_PTR_RETURN_NULL(coord);
+    double sinY = 0.0;
+    double cosY = 0.0;
+    double sinX = 0.0;
+    double cosX = 0.0;
+    double x = 0.0;
+    double y = 0.0;
+    double dx = 0.0;
+
+    if (out == NULL) {
+        out = (psSphere* ) psAlloc(sizeof(psSphere));
+    }
+
+    x = coord->r;
+    y = coord->d;
+    dx = x - transform->xo;
+    sinY = cos(y) * sin(dx) * transform->sinPhi + sin(y) * transform->cosPhi;
+    cosY = sqrt(1.0 - sinY * sinY);
+    sinX = (cos(y) * sin(dx) * transform->cosPhi - sin(y) * transform->sinPhi) / cos(y);
+    cosX = cos(y) * cos(dx) / cos(y);
+
+    out->r = atan2(sinX, cosX) + transform->Xo;
+    out->d = atan2(sinY, cosY);
+
+    return (out);
+}
+
+psSphereTransform* psSphereTransformICRStoEcliptic(psTime time)
+{
+    struct tm *tmTime = psTimeToTM(&time);
+    double year = (double)(1900 + tmTime->tm_year);
+    double T = year / 100.0;
+    double phi = -23.452294 + 0.013013 * T + 0.000001639 * T * T - 0.000000503 * T * T * T;
+    double Xo = 0.0;
+    double xo = 0.0;
+
+    psFree(tmTime);
+    return (psSphereTransformAlloc(phi, Xo, xo));
+}
+
+psSphereTransform* psSphereTransformEcliptictoICRS(psTime time)
+{
+    struct tm *tmTime = psTimeToTM(&time);
+    double year = (double)(1900 + tmTime->tm_year);
+    double T = year / 100.0;
+    double phi = +23.452294 - 0.013013 * T - 0.000001639 * T * T + 0.000000503 * T * T * T;
+    double Xo = 0.0;
+    double xo = 0.0;
+
+    psFree(tmTime);
+    return (psSphereTransformAlloc(phi, Xo, xo));
+}
+
+psSphereTransform* psSphereTransformICRStoGalatic(void)
+{
+    return (psSphereTransformAlloc(62.6, 282.25, 33.0));
+}
+
+psSphereTransform* psSphereTransformGalatictoICRS(void)
+{
+    return (psSphereTransformAlloc(-62.6, 33.0, 282.25));
+}
+
+/******************************************************************************
+XXX: Waiting for the definition of the PS_PROJ_PAR projection.
+XXX: Waiting for the definition of the PS_PROJ_GLS projection.
+XXX: get rid of the psAborts
+ *****************************************************************************/
+psPlane* psProject(const psSphere* coord,
+                   const psProjection* projection)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(coord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(projection);
+
+    float R = 0.0;
+    float alpha = 0.0;
+    psPlane* tmp = (psPlane* ) psAlloc(sizeof(psPlane));
+
+    if (projection->type == PS_PROJ_TAN) {
+        R = PS_COT(coord->r) * (180.0 / M_PI);
+        tmp->x = R * sin(coord->d);
+        tmp->y = R * cos(coord->d);
+
+    } else if (projection->type == PS_PROJ_SIN) {
+        R = cos(coord->r) * (180.0 / M_PI);
+        tmp->x = R * sin(coord->d);
+        tmp->y = R * cos(coord->d);
+
+    } else if (projection->type == PS_PROJ_CAR) {
+        tmp->x = coord->d;
+        tmp->y = coord->r;
+
+    } else if (projection->type == PS_PROJ_MER) {
+        tmp->x = coord->d;
+        tmp->y = log(tan(45.0 + (0.5 * coord->r))) * 180.0 / M_PI;
+
+    } else if (projection->type == PS_PROJ_AIT) {
+        alpha = 1.0 / ((180.0 / M_PI) * sqrt(1.0 + (cos(coord->r) *
+                                             cos(0.5 * coord->d) * 0.5)));
+
+        tmp->x = 2.0 * alpha * cos(coord->r) * sin(0.5 * coord->d);
+        tmp->y = alpha * sin(coord->d);
+
+    } else if (projection->type == PS_PROJ_PAR) {
+        psAbort(__func__, "The projection type PS_PROJ_PAR is undefined.\n");
+
+    } else if (projection->type == PS_PROJ_GLS) {
+        psAbort(__func__, "The projection type PS_PROJ_GLS is undefined.\n");
+    } else {
+        psAbort(__func__, "Unknown projection type.\n");
+    }
+
+    return (tmp);
+}
+
+/******************************************************************************
+XXX: Waiting for the definition of the PS_PROJ_PAR projection.
+XXX: Waiting for the definition of the PS_PROJ_GLS projection.
+XXX: get rid of the psAborts
+ *****************************************************************************/
+psSphere* psDeproject(const psPlane* coord,
+                      const psProjection* projection)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(coord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(projection);
+
+    float R = 0.0;
+    float chu = 0.0;
+    float chu1 = 0.0;
+    float chu2 = 0.0;
+    psSphere* tmp = (psSphere* ) psAlloc(sizeof(psSphere));
+
+    if (projection->type == PS_PROJ_TAN) {
+        R = sqrt((coord->x * coord->x) + (coord->y * coord->y));
+        tmp->d = p_psArg(-coord->y, coord->x);
+        tmp->r = atan(180.0 / (R * M_PI));
+
+    } else if (projection->type == PS_PROJ_SIN) {
+        R = sqrt((coord->x * coord->x) + (coord->y * coord->y));
+        tmp->d = p_psArg(-coord->y, coord->x);
+        tmp->r = acos((R * M_PI) / 180.0);
+
+    } else if (projection->type == PS_PROJ_CAR) {
+        tmp->d = coord->x;
+        tmp->r = coord->y;
+
+    } else if (projection->type == PS_PROJ_MER) {
+        tmp->d = coord->x;
+        tmp->r = (2.0 * atan(exp((coord->y * M_PI / 180.0)))) - 180.0;
+
+    } else if (projection->type == PS_PROJ_AIT) {
+        chu1 = (coord->x * M_PI) / 720.0;
+        chu1 *= chu1;
+        chu2 = (coord->y * M_PI) / 360.0;
+        chu2 *= chu2;
+        chu = sqrt(1.0 - chu1 - chu2);
+        tmp->d = 2.0 * p_psArg((2.0 * chu * chu) - 1.0, (coord->x * chu * M_PI) / 360.0);
+        tmp->r = asin((coord->y * chu * M_PI) / 180.0);
+
+    } else if (projection->type == PS_PROJ_PAR) {
+        psAbort(__func__, "The projection type PS_PROJ_PAR is undefined.\n");
+
+    } else if (projection->type == PS_PROJ_GLS) {
+        psAbort(__func__, "The projection type PS_PROJ_GLG is undefined.\n");
+    } else {
+        psAbort(__func__, "Unknown projection type.\n");
+    }
+
+    return (tmp);
+}
+
+/******************************************************************************
+The basic idea is to project both positions onto the linear plane, with
+position1 at the center, then calculate the linear offset between those
+projections.
+ 
+XXX: Do I need to check for unacceptable transformation parameters?  Maybe,
+     if the points are on the North/South Pole, etc?
+ 
+XXX: Do I need to somehow scale this projection?
+ 
+XXX: Does PS_LINEAR mode make sense?  The result must be returned in psSphere
+     regardless of the mode.
+ 
+XXX: How to compound errors?
+ *****************************************************************************/
+psSphere* psSphereGetOffset(const psSphere* restrict position1,
+                            const psSphere* restrict position2,
+                            psSphereOffsetMode mode,
+                            psSphereOffsetUnit unit)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(position1);
+    PS_CHECK_NULL_PTR_RETURN_NULL(position2);
+
+    psPlane* lin;
+    psProjection proj;
+    psSphere* tmp;
+
+    if (mode == PS_LINEAR) {
+        proj.R = position1->r;
+        proj.D = position1->d;
+        proj.Xs = 1.0;
+        proj.Ys = 1.0;
+        proj.type = PS_PROJ_TAN;
+
+        lin = psProject(position2, &proj);
+        tmp = psDeproject(lin, &proj);
+        psFree(lin);
+
+        // XXX: Do we need to convert units in tmp?
+        return (tmp);
+    } else if (mode == PS_SPHERICAL) {
+        tmp = (psSphere* ) psAlloc(sizeof(psSphere));
+        tmp->r = position2->r - position1->r;
+        tmp->d = position2->d - position1->d;
+
+        // Wrap these to an acceptable range.  This assumes that all
+        // angles are in radians.
+        tmp->r = fmod(tmp->r, 2*M_PI);
+        tmp->d = fmod(tmp->d, 2*M_PI);
+        tmp->rErr = 0.0;
+        tmp->dErr = 0.0;
+
+        if (unit == PS_ARCSEC) {
+            tmp->r = (tmp->r * 180.0 * 60.0 * 60.0) / M_PI;
+            tmp->d = (tmp->d * 180.0 * 60.0 * 60.0) / M_PI;
+        } else if (unit == PS_ARCMIN) {
+            tmp->r = (tmp->r * 180.0 * 60.0) / M_PI;
+            tmp->d = (tmp->d * 180.0 * 60.0) / M_PI;
+        } else if (unit == PS_DEGREE) {
+            tmp->r = (tmp->r * 180.0) / M_PI;
+            tmp->d = (tmp->d * 180.0) / M_PI;
+        } else if (unit == PS_RADIAN) {}
+        else {
+            psAbort(__func__, "Unknown offset unit: 0x%x\n", unit);
+        }
+
+        return (tmp);
+    }
+    psAbort(__func__, "Unrecognized offset mode\n");
+    return (NULL);
+}
+
+/******************************************************************************
+XXX: Do we need to check for unacceptable transformation parameters?  Maybe,
+     if the points are on the North/South Pole, etc?
+ 
+XXX: Do we need to somehow scale this projection?
+ 
+XXX: I copied the algorithm from the ADD exactly.
+ 
+XXX: Should we compound errors?
+ *****************************************************************************/
+
+psSphere* psSphereSetOffset(const psSphere* restrict position,
+                            const psSphere* restrict offset,
+                            psSphereOffsetMode mode,
+                            psSphereOffsetUnit unit)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(position);
+    PS_CHECK_NULL_PTR_RETURN_NULL(offset);
+
+    psPlane lin;
+    psSphere* tmp;
+    psProjection proj;
+    double tmpR = 0.0;
+    double tmpD = 0.0;
+
+    if (mode == PS_LINEAR) {
+        proj.R = position->r;
+        proj.D = position->d;
+        proj.Xs = 1.0;
+        proj.Ys = 1.0;
+        proj.type = PS_PROJ_TAN;
+
+        lin.x = offset->r;
+        lin.y = offset->d;
+
+        tmp = psDeproject(&lin, &proj);
+        return (tmp);
+
+    } else if (mode == PS_SPHERICAL) {
+        if (unit == PS_ARCSEC) {
+            tmpR = (M_PI * offset->r) / (180.0 * 60.0 * 60.0);
+            tmpD = (M_PI * offset->d) / (180.0 * 60.0 * 60.0);
+        } else if (unit == PS_ARCMIN) {
+            tmpR = (M_PI * offset->r) / (180.0 * 60.0);
+            tmpD = (M_PI * offset->d) / (180.0 * 60.0);
+        } else if (unit == PS_DEGREE) {
+            tmpR = (M_PI * offset->r) / (180.0);
+            tmpD = (M_PI * offset->d) / (180.0);
+        } else if (unit == PS_RADIAN) {
+            tmpR = offset->r;
+            tmpD = offset->d;
+        } else {
+            psAbort(__func__, "Unknown offset unit: 0x%x\n", unit);
+        }
+
+        tmp = (psSphere* ) psAlloc(sizeof(psSphere));
+        tmp->r = position->r + tmpR;
+        tmp->r = fmod(tmp->r, 2.0*M_PI);
+        tmp->d = position->d + tmpD;
+        tmp->d = fmod(tmp->d, 2.0*M_PI);
+        tmp->rErr = 0.0;
+        tmp->dErr = 0.0;
+
+        return (tmp);
+    }
+    psAbort(__func__, "Unrecognized offset mode\n");
+    return (NULL);
+}
Index: /branches/rel3/psLib/src/astro/psCoord.h
===================================================================
--- /branches/rel3/psLib/src/astro/psCoord.h	(revision 2163)
+++ /branches/rel3/psLib/src/astro/psCoord.h	(revision 2163)
@@ -0,0 +1,298 @@
+
+/** @file  psCoord.h
+*
+*  @brief Contains basic coordinate transformation definitions and operations
+*
+*  This file defines the basic types for astronomical coordinate 
+*  transformation
+*
+*  @ingroup CoordinateTransform
+*
+*  @author George Gusciora, MHPCC
+*
+*  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-12 01:34:09 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#ifndef PS_COORD_H
+#define PS_COORD_H
+
+#include "psType.h"
+#include "psImage.h"
+#include "psArray.h"
+#include "psList.h"
+#include "psFunctions.h"
+#include "psTime.h"
+
+/// @addtogroup CoordinateTransform
+/// @{
+
+/** Euclidiean Coordinate System.
+ *
+ *  Both detector and sky positions will be used extensively in the IPP. One
+ *  coordinate system to be used is linear coordinates which conform to 
+ *  Euclidean geometry. 
+ *
+ */
+typedef struct
+{
+    double x;                   ///< x position
+    double y;                   ///< y position
+    double xErr;                ///< Error in x position
+    double yErr;                ///< Error in y position
+}
+psPlane;
+
+/** Angular Coordinate System
+ *
+ *  Both detector and sky positions will be used extensively in the IPP. One 
+ *  coordinate system to be used is angular coordinates for which additional 
+ *  care must often be taken in comparison to a euclidiean coordinate system.
+ *
+ */
+typedef struct psSphere
+{
+    double r;                   ///< RA
+    double d;                   ///< Dec
+    double rErr;                ///< Error in RA
+    double dErr;                ///< Error in Dec
+}
+psSphere;
+
+/** 2D Polynomial Transform
+ *
+ *  A transform between coordinate systems that consists simply of two 2D 
+ *  polynomials to transform both components - the output coordinates depend 
+ *  only on the input coordinates and no other quantities of objects at those
+ *  coordinates. 
+ *
+ */
+typedef struct
+{
+    psDPolynomial2D* x;         ///< 2D polynomial transform of X coordinates
+    psDPolynomial2D* y;         ///< 2D polynomial transform of Y coordinates
+}
+psPlaneTransform;
+
+/** 4D Polynomial Transform
+ *
+ *  A transform between coordinate systems that consists of two 4D polynomials
+ *  in which the output coordinates are also specified to be a function of the 
+ *  magnitude and color of the object with the given coordinates. This type of 
+ *  coordinate transformation is necessary to represent the (color-dependent) 
+ *  optical distortions caused by the atmosphere and camera optics, and the 
+ *  possibly effects of charge transfer inefficiency.
+ *
+ *  The lowest two terms are the x and y axis of the target system.  The higher
+ *  two terms may represent magnitude and color terms.
+ */
+typedef struct
+{
+    psDPolynomial4D* x;         ///< 4D polynomial transform of X coordinates
+    psDPolynomial4D* y;         ///< 4D polynomial transform of Y coordinates
+}
+psPlaneDistort;
+
+/** Spherical Transform Definition
+ *
+ *  We need to be able to convert between ICRS, Galactic and Ecliptic 
+ *  coordinates, and potentially between arbitrary spherical coordinate 
+ *  systems. All of these basic spherical transformations represent rotations 
+ *  of the spherical coordinate reference. We specify a general 
+ *  transformation function which takes a structure, psSphereTransform, 
+ *  defining the transformation between two spherical coordinate systems 
+ *
+ */
+typedef struct
+{
+    double sinPhi;              ///< sin of North Pole lattitude
+    double cosPhi;              ///< cos of North Pole lattitude
+    double Xo;                  ///< First PT of Ares lon
+    double xo;                  ///< First PT of Ares equiv lon
+}
+psSphereTransform;
+
+/** Projection type for projection/deprojection
+ * 
+ *  @see psProject, psDeproject
+ *
+ */
+typedef enum {
+    PS_PROJ_TAN,                ///< Tangent projection
+    PS_PROJ_SIN,                ///< Sine projection
+    PS_PROJ_AIT,                ///< Aitoff projection
+    PS_PROJ_PAR,                ///< Par projection
+    PS_PROJ_GLS,                ///< GLS projection
+    PS_PROJ_CAR,                ///< CAR projection
+    PS_PROJ_MER,                ///< MER projection
+    PS_PROJ_NTYPE               ///< Number of types; must be last.
+} psProjectionType;
+
+/** Parameter set for projection/deprojection
+ * 
+ *  @see psProject, psDeproject
+ *
+ */
+typedef struct
+{
+    double R;                   ///< Coordinates of projection center
+    double D;                   ///< Coordinates of projection center
+    double Xs;                  ///< plate-scale in X direction
+    double Ys;                  ///< plate-scale in Y direction
+    psProjectionType type;      ///< Projection type
+}
+psProjection;
+
+/** Mode for Offset calculation between two sky positions
+ *
+ *  @see  psSphereGetOffset, psSphereSetOffset
+ *
+ */
+typedef enum {
+    PS_SPHERICAL,               ///< offset corresponds to an angular offset
+    PS_LINEAR                   ///< offset corresponds to a linear offset
+} psSphereOffsetMode;
+
+/** The units of the offset
+ *
+ *  @see  psSphereGetOffset, psSphereSetOffset
+ *
+ */
+typedef enum {
+    PS_ARCSEC,                  ///< Arcseconds
+    PS_ARCMIN,                  ///< Arcminutes
+    PS_DEGREE,                  ///< Degrees
+    PS_RADIAN                   ///< Radians
+} psSphereOffsetUnit;
+
+/** Applies the psPlaneTransform transform to a specified coordinate
+ *
+ *  @return psPlane*     resulting coordinate based on transform
+ */
+psPlane* psPlaneTransformApply(
+    psPlane* out,                      ///< a psPlane to recycle.  If NULL, a new one is generated.
+    const psPlaneTransform* transform, ///< the transform to apply
+    const psPlane* coords              ///< the coordinate to apply the transform above.
+);
+
+/** Applies the psPlaneDistort transform to a specified coordinate
+ *
+ *  @return psPlane*     resulting coordinate based on transform
+ */
+psPlane* psPlaneDistortApply(
+    psPlane* out,                      ///< a psPlane to recycle.  If NULL, a new one is generated.
+    const psPlaneDistort* transform,   ///< the transform to apply
+    const psPlane* coords,             ///< the coordinate to apply the transform above.
+    float term3,                       ///< third term -- maybe magnitude
+    float term4                        ///< forth term -- maybe color
+);
+
+/** Allocator for psSphereTransform
+ *
+ *  @return psSphereTransform*         newly allocated struct
+ */
+psSphereTransform* psSphereTransformAlloc(
+    double NPlat,                      ///< north pole latitude
+    double Xo,                         ///< First PT of Ares lon
+    double xo                          ///< First PT of Ares equiv lon
+);
+
+/** Applies the psSphereTransform transform for a specified coordinate
+ *
+ *  @return psSphere*      resulting coordinate based on transform
+ */
+psSphere* psSphereTransformApply(
+    psSphere* out,                     ///< a psSphere to recycle.  If NULL, a new one is generated.
+    const psSphereTransform* transform,///< the transform to apply
+    const psSphere* coord              ///< the coordinate to apply the transform above.x
+);
+
+/** Creates the appropriate transform for converting from ICRS to Ecliptic
+ *  coordinate systems.
+ *
+ *  @return psSphereTransform*     transform for ICRS->Ecliptic coordinate systems
+ */
+psSphereTransform* psSphereTransformICRStoEcliptic(
+    psTime time                        ///< the time for which the resulting transform will be valid
+);
+
+/** Creates the appropriate transform for converting from Ecliptic to ICRS
+ *  coordinate systems.
+ *
+ *  @return psSphereTransform*     transform for Ecliptic->ICRS coordinate systems
+ */
+psSphereTransform* psSphereTransformEcliptictoICRS(
+    psTime time                        ///< the time for which the resulting transform will be valid
+);
+
+/** Creates the appropriate transform for converting from ICRS to Galatic
+ *  coordinate systems.
+ *
+ */
+psSphereTransform* psSphereTransformICRStoGalatic(void);
+
+/** Creates the appropriate transform for converting from Galatic to ICRS
+ *  coordinate systems.
+ *
+ */
+psSphereTransform* psSphereTransformGalatictoICRS(void);
+
+/** Projects a spherical coordinate to a linear coordinate system
+ *
+ *  @return psPlane*    projected coordinate
+ */
+psPlane* psProject(
+    const psSphere* coord,             ///< coordinate to project
+    const psProjection* projection     ///< parameters of the projection
+);
+
+/** Reverse projection of a linear coordinate to a spherical coordinate system
+ *
+ *  @return psPlane*    projected coordinate
+ */
+psSphere* psDeproject(
+    const psPlane* coord,              ///< coordinate to project
+    const psProjection* projection     ///< parameters of the projection
+);
+
+/** Determines the offset (RA,Dec) on the sky between two positions.
+ *
+ *  Both an offset mode and an offset unit may be defined. The mode may be 
+ *  either PS_SPHERICAL, in which case the specified offset corresponds to an 
+ *  offset in angles, or it may be PS_LINEAR, in which case the offset 
+ *  corresponds to a linear offset in a local projection. The offset unit may 
+ *  be in one of PS_ARCSEC, PS_ARCMIN, PS_DEGREE, and PS_RADIAN, which 
+ *  specifies the units of the offset only.
+ *
+ *  @return psSphere*    the offset between position1 and position2
+ */
+psSphere* psSphereGetOffset(
+    const psSphere* restrict position1,
+    const psSphere* restrict position2,
+    psSphereOffsetMode mode,
+    psSphereOffsetUnit unit
+);
+
+/** Applies the given offset to a coordinate.
+ *
+ *  Both an offset mode and an offset unit may be defined. The mode may be 
+ *  either PS_SPHERICAL, in which case the specified offset corresponds to an 
+ *  offset in angles, or it may be PS_LINEAR, in which case the offset 
+ *  corresponds to a linear offset in a local projection. The offset unit may 
+ *  be in one of PS_ARCSEC, PS_ARCMIN, PS_DEGREE, and PS_RADIAN, which 
+ *  specifies the units of the offset only.
+ *
+ *  @return psSphere*    the given position with the given offset applied.
+ */
+psSphere* psSphereSetOffset(
+    const psSphere* restrict position,
+    const psSphere* restrict offset,
+    psSphereOffsetMode mode,
+    psSphereOffsetUnit unit
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/astro/psTime.c
===================================================================
--- /branches/rel3/psLib/src/astro/psTime.c	(revision 2163)
+++ /branches/rel3/psLib/src/astro/psTime.c	(revision 2163)
@@ -0,0 +1,1085 @@
+/** @file  psTime.c
+ *
+ *  @brief Definitions for time, time utilities, and conversion functions for use with psLib astronomy
+ *  functions.
+ *
+ *  A collection of functions are required by psLib to manipulate time data. These functions primarily consist
+ *  of conversions between specific time formats.  PSLib currently uses the UNIX timeval time system as the
+ *  base upon which International Atomic Time (TAI) and Universal Time Coordinated (UTC) are calculated. TAI
+ *  time varies over time due to the earth's rotation and the movement of the continental plates.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.34 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-15 19:10:50 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "psTime.h"
+#include "psError.h"
+#include "psMemory.h"
+#include "psAbort.h"
+#include "psImage.h"
+#include "psCoord.h"
+#include "psString.h"
+
+#include "psAstronomyErrors.h"
+
+#ifndef SER7_FILE
+#define SER7_FILE "../../data/ser7.dat"
+#pragma warning SER7_FILE was not defined in the makefile.
+#endif
+
+#ifndef TAIUTC_FILE
+#define TAIUTC_FILE "../../data/tai-utc.dat"
+#pragma warning TAIUTC_FILE was not defined in the makefile.
+#endif
+
+/** Sidereal angular conversion from seconds to radians for GMST in seconds (i.e. pi/(180*240)) */
+#define S2R (7.272205216643039903848711535369e-5)
+
+/** Two times pi with double precision accuracy */
+#define TWOPI (2.0*M_PI)
+
+/** Conversion from radians to degrees */
+#define R2DEG = (180.0/M_PI)
+
+                /** Maximum length of time string */
+                #define MAX_TIME_STRING_LENGTH 256
+
+                /** Seconds per minute */
+                #define  SEC_PER_MINUTE 60.0
+
+                /** Seconds per hour */
+                #define  SEC_PER_HOUR (60.0*SEC_PER_MINUTE)
+
+                /** Seconds per day */
+                #define  SEC_PER_DAY (24.0*SEC_PER_HOUR)
+
+                /** Seconds per year */
+                #define  SEC_PER_YEAR (365.0*SEC_PER_DAY)
+
+                /** Microseconds per day */
+                #define USEC_PER_DAY 86400000000.0
+
+                /** Max size of a line read */
+                #define LINESIZE 1024
+
+                /** Preprocessor macro to check for null psTime struct */
+                #define CHECK_NULL_TIME(TIME,RETURN) \
+                if(TIME == NULL) { \
+                    psError(__func__,"NULL value not allowed"); \
+                    return RETURN; \
+                }
+
+                /** Preprocessor macro to allocate psTime struct */
+                #define ALLOC_TIME(TIME) \
+                TIME = (psTime*)psAlloc(sizeof(psTime)); \
+if (TIME == NULL) { \
+    psAbort(__func__, " : Line %d - Failed to allocate memory", __LINE__); \
+} \
+TIME->sec = 0; \
+TIME->usec = 0; \
+TIME->type = PS_TIME_TAI;
+
+/** Read TAI/UTC data file.
+ *
+ *  Reads TAI/UTC data file.
+ *
+ *  @return  psImage*: Two-dimensional array with table data.
+ */
+static psImage* readTaiUtcFile(
+    const char *fileName                      ///< Name of file to read.
+);
+
+
+/** Read SER7 data file.
+ *
+ *  Reads SER7 data file.
+ *
+ *  @return  psImage*: Two-dimensional array with table data.
+ */
+static psImage* readSer7File(
+    const char *fileName                      ///< Name of file to read.
+);
+
+
+/** Read finals data file.
+ *
+ *  Reads finals data file.
+ *
+ *  @return  psImage*: Two-dimensional array with table data.
+ */
+/* not yet used
+static psImage* readFinalsFile(
+    char *fileName                      ///< Name of file to read.
+);
+*/
+
+/** Read EOPC data file.
+ *
+ *  Reads EOPC data file.
+ *
+ *  @return  psImage*: Two-dimensional array with table data.
+ */
+/* not yet used
+static psImage* readEopcFile(
+    char *fileName                      ///< Name of file to read.
+);
+*/
+
+/** Lookup and interpolate TAI-UTC data
+ *
+ *  Interpolates TAI-UTC data, given time in MJD format.
+ *
+ *  @return  double: Interpolated value.
+ */
+static double lookupTaiUtcTable(
+    const psTime *time                        ///< time to lookup.
+);
+
+/** Lookup and interpolate polar or UT1-UTC data
+ *
+ *  Interpolates TAI-UT1 or polar coordinate data, given time in MJD format.
+ *
+ *  @return  double: Interpolated value.
+ */
+static double lookupSer7Table(
+    const psTime *time,                        ///< time to lookup.
+    int col                              ///< Column to lookup.
+);
+
+static psImage* readTaiUtcFile(const char *fileName)
+{
+    char line[LINESIZE];
+    int j = 0;
+    int maxLines = 100;
+    psF64 *ptr = NULL;
+    psImage *table = NULL;
+    FILE *fd = NULL;
+
+
+    fd=fopen(fileName, "r");
+    if(fd==NULL) {
+        psError(__func__, " : Line %d - Couldn't open %s", __LINE__, fileName);
+        return NULL;
+    }
+
+    // Table shouldn't be larger than 100 rows. Select columns are read based on indices.
+    table  = psImageAlloc(4, maxLines, PS_TYPE_F64);
+
+    while(fgets(line, LINESIZE, fd) != NULL) {
+        if(j>=maxLines) {
+            psError(__func__, " : Line %d - Too many rows in file. Max size: %d", __LINE__, maxLines);
+            return NULL;
+            psFree(table);
+        }
+
+        ptr = table->data.F64[j++];
+        *ptr = atof(line+16);                  // MJD
+        *(ptr+1) = atof(line+38);              // TAI-UTC
+        *(ptr+2) = atof(line+59);              // Contant #1
+        *(ptr+3) = atof(line+69);              // Contant #2
+    }
+
+    *(unsigned int *)&table->numRows = j;
+
+    p_psMemSetPersistent(table,true);
+    p_psMemSetPersistent(table->data.V,true);
+    p_psMemSetPersistent(table->rawDataBuffer,true);
+
+    return table;
+}
+
+static psImage* readSer7File(const char *fileName)
+{
+    bool beginRecord = false;
+    char line[LINESIZE];
+    int j = 0;
+    int maxLines = 400;
+    psImage *table = NULL;
+    FILE *fd = NULL;
+
+
+    fd=fopen(fileName, "r");
+    if(fd==NULL) {
+        psError(__func__, " : Line %d - Couldn't open %s", __LINE__, fileName);
+        return NULL ;
+    }
+
+    // Table shouldn't be larger than 400 rows. All columns in area of interest are read.
+    table  = psImageAlloc(7, maxLines, PS_TYPE_F64);
+
+    while(fgets(line, LINESIZE, fd) != NULL) {
+
+        // Stop parsing after finding "These" in data file after read has began
+        if(beginRecord) {
+            if(strstr(line, "These")!=NULL) {
+                beginRecord = false;
+                break;
+            }
+
+            if(j>=maxLines) {
+                psError(__func__, " : Line %d - Too many rows in file. Max size: %d", __LINE__, maxLines);
+                return NULL;
+                psFree(table);
+            }
+            psF64 *ptr = table->data.F64[j++];
+            sscanf(line, "%lf %lf %lf %lf %lf %lf %lf", ptr, ptr+1, ptr+2, ptr+3, ptr+4, ptr+5, ptr+6);
+        }
+
+        // Start parsing after finding "x(arcsec)" in data file
+        if(strstr(line, "x(arcsec)") != NULL) {
+            beginRecord = true;
+        }
+    }
+    *(unsigned int *)&table->numRows = j;
+
+    p_psMemSetPersistent(table,true);
+    p_psMemSetPersistent(table->data.V,true);
+    p_psMemSetPersistent(table->rawDataBuffer,true);
+
+    return table;
+}
+
+/* Not yet used...
+static psImage* readEopcFile(char *fileName)
+{
+    char line[LINESIZE];
+    int i = 0;
+    int j = 0;
+    int maxLines = 2500;
+    psImage *table = NULL;
+    FILE *fd = NULL;
+ 
+ 
+    fd=fopen(fileName, "r");
+    if(fd==NULL) {
+        psError(__func__, " : Line %d - Couldn't open %s", __LINE__, fileName);
+        return NULL ;
+    }
+ 
+    // Table shouldn't be larger than 2500 rows. All columns are read.
+    table  = psImageAlloc(11, maxLines, PS_TYPE_F64);
+    for(i=0; i<3; i++) {
+        if((fgets(line, LINESIZE, fd) != NULL)) {
+            psError(__func__, " : Line %d - Error reading %s", __LINE__, fileName);
+        }
+    }
+ 
+    while(fgets(line, LINESIZE, fd) != NULL) {
+        if(j>=maxLines) {
+            psError(__func__, " : Line %d - Too many rows in file. Max size: %d", __LINE__, maxLines);
+            return NULL;
+            psFree(table);
+        }
+        psF64 *ptr = table->data.F64[j++];
+        sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
+               ptr, ptr+1, ptr+2, ptr+3, ptr+4, ptr+5, ptr+6, ptr+7, ptr+8, ptr+9, ptr+10);
+    }
+ 
+    *(unsigned int *)&table->numRows = j;
+ 
+    return table;
+}
+ 
+static psImage* readFinalsFile(char *fileName)
+{
+    char line[LINESIZE];
+    int j = 0;
+    int maxLines = 15000;
+    psImage *table = NULL;
+    FILE *fd = NULL;
+ 
+ 
+    fd=fopen(fileName, "r");
+    if(fd==NULL) {
+        psError(__func__, " : Line %d - Couldn't open %s", __LINE__, fileName);
+        return NULL ;
+    }
+ 
+    // Table shouldn't be larger than 15000 rows. Select columns are read.
+    table  = psImageAlloc(6, maxLines, PS_TYPE_F64);
+    while(fgets(line, LINESIZE, fd) != NULL) {
+        if(j>=maxLines) {
+            psError(__func__, " : Line %d - Too many rows in file. Max size: %d", __LINE__, maxLines);
+            return NULL;
+            psFree(table);
+        }
+ 
+        psF64 *ptr = table->data.F64[j++];
+        ptr = table->data.F64[j++];
+ 
+        // Sometimes there are blank entries in this table, so check for a space to determine if there is no entry
+        if(*(line+7) == ' ') {                   // MJD
+            *ptr = 0.0;
+        } else {
+            *ptr = atof(line+7);
+        }
+ 
+        if(*(line+18) == ' ') {                  // Polar motion X
+            *(ptr+1) = 0.0;
+        } else {
+            *(ptr+1) = atof(line+18);
+        }
+ 
+        if(*(line+27) == ' ') {                  // Polar motion X error
+            *(ptr+2) = 0.0;
+        } else {
+            *(ptr+2) = atof(line+27);
+        }
+ 
+        if(*(line+37) == ' ') {                  // Polar motion Y
+            *(ptr+3) = 0.0;
+        } else {
+            *(ptr+3) = atof(line+37);
+        }
+ 
+        if(*(line+46) == ' ') {                  // Polar motion Y error
+            *(ptr+4) = 0.0;
+        } else {
+            *(ptr+4) = atof(line+46);
+        }
+ 
+        if(*(line+58) == ' ') {                  // UT1-UTC
+            *(ptr+5) = 0.0;
+        } else {
+            *(ptr+5) = atof(line+58);
+        }
+    }
+ 
+    *(unsigned int *)&table->numRows = j;
+ 
+    return table;
+}
+*/
+
+static double lookupTaiUtcTable(const psTime *time)
+{
+    int hiIdx = 0;
+    int loIdx = 0;
+    int numRows = 0;
+    double jd = 0.0;
+    double mjd = 0.0;
+    double out = 0.0;
+    double denom = 0.0;
+    double const1 = 0.0;
+    double const2 = 0.0;
+    double const3 = 0.0;
+    static psImage* table = NULL;
+
+    if (table == NULL) {
+        table = readTaiUtcFile(TAIUTC_FILE);
+        if (table == NULL) {
+            psAbort(__func__,"Failed to read tai-utc.dat file");
+        }
+    }
+
+    // Number of rows is the number of rows of data read from the data file
+    numRows = table->numRows;
+
+    // Determine Julian and modified Julian dates used in table lookup and time delta calculation
+    jd = psTimeToJD(time);
+    mjd = psTimeToMJD(time);
+
+    // Variable in should be in MJD format
+    if(jd < table->data.F64[0][0]) {                                        // MJD time before start of table
+        return 0.0;
+    } else if(jd > table->data.F64[numRows-1][0]) {                         // MJD time after end of table
+        return table->data.F64[numRows-1][1];
+    } else {                                                                // All other times..interpolate
+        while(jd > table->data.F64[hiIdx][0]) {
+            hiIdx++;
+            if(hiIdx >= numRows) {
+                psError(__func__, " : Line %d - High index too big. Value: %d", __LINE__, hiIdx);
+                return 0.0;
+            }
+        }
+        loIdx = hiIdx--;
+        if(loIdx < 0) {
+            psError(__func__, " : Line %d - Low index too small. Value: %d", __LINE__, loIdx);
+            return 0.0;
+        }
+
+        denom = table->data.F64[hiIdx][0]-table->data.F64[loIdx][0];
+        if(fabs(denom) < FLT_EPSILON) {
+            psError(__func__, " : Line %d - Divide by zero error during interpolation", __LINE__);
+            return 0.0;
+        } else {
+
+            // Interpolate three constants required to calculate TAI-UTC
+            const1 = table->data.F64[loIdx][1]+(table->data.F64[hiIdx][1]-table->data.F64[loIdx][1])
+                     *(jd-table->data.F64[loIdx][0])/denom;
+
+            const2 = table->data.F64[loIdx][2]+(table->data.F64[hiIdx][2]-table->data.F64[loIdx][2])
+                     *(jd-table->data.F64[loIdx][0])/denom;
+
+            const3 = table->data.F64[loIdx][3]+(table->data.F64[hiIdx][3]-table->data.F64[loIdx][3])
+                     *(jd-table->data.F64[loIdx][0])/denom;
+        }
+    }
+
+    out = const1 + (mjd - const2) * const3;
+
+    return out;
+}
+
+static double lookupSer7Table(const psTime *time, int col)
+{
+    int hiIdx = 0;
+    int loIdx = 0;
+    int numRows = 0;
+    double out = 0.0;
+    double denom = 0.0;
+    double mjdUtc = 0.0;
+    static psImage* table = NULL;
+
+    if (table == NULL) {
+        table = readSer7File(SER7_FILE);
+        if (table == NULL) {
+            psAbort(__func__,"Failed to read the ser7.dat file.");
+        }
+    }
+
+    // Number of rows is the number of rows of data read from the data file
+    numRows = table->numRows;
+
+    // Interpolation value in should be in MJD format
+    mjdUtc = psTimeToMJD(time);
+    if(mjdUtc < table->data.F64[0][3]) {                                    // MJD time before start of table
+        psError(__func__, " : Line %d - MJD too small. Value: %d", __LINE__, mjdUtc);
+
+    } else if(mjdUtc > table->data.F64[numRows-1][3]) {                     // MJD time after end of table
+        psError(__func__, " : Line %d - MJD too big. Value: %d", __LINE__, mjdUtc);
+    } else {                                                                // All other times..interpolate
+        while(mjdUtc > table->data.F64[hiIdx][3]) {
+            hiIdx++;
+            if(hiIdx >= numRows) {
+                psError(__func__, " : Line %d - High index too big. Value: %d", __LINE__, hiIdx);
+                return 0.0;
+            }
+        }
+
+        loIdx = hiIdx--;
+        if(loIdx < 0) {
+            psError(__func__, " : Line %d - Low index too small. Value: %d", __LINE__, loIdx);
+        }
+
+        denom = table->data.F64[hiIdx][3] - table->data.F64[loIdx][3];
+        if(fabs(denom) < FLT_EPSILON) {
+            psError(__func__, " : Line %d - Dividie by zero error during interpolation", __LINE__);
+        } else {
+            out = table->data.F64[loIdx][col]+(table->data.F64[hiIdx][col]-table->data.F64[loIdx][col])
+                  *(mjdUtc-table->data.F64[loIdx][3])/denom;
+        }
+    }
+
+    return out;
+}
+
+psTime* psTimeGetTime(psTimeType type)
+{
+    struct timeval now;
+    psTime *time = NULL;
+
+
+    // Allocate psTime struct
+    ALLOC_TIME(time);
+
+    if (gettimeofday(&now, (struct timezone *)0) == -1) {
+        psError(__func__, " : Line %d - Failed to get time", __LINE__);
+        return NULL;
+    }
+
+    // Convert timeval time to psTime
+    time->sec = now.tv_sec;
+    time->usec = now.tv_usec;
+    time->type = type;
+
+    // Add most leapseconds to UTC time to get TAI time if necessary
+    if(type == PS_TIME_TAI) {
+        time->sec += psTimeGetTAIDelta(time);
+    }
+
+    return time;
+}
+
+psTime* psTimeConvert(psTime *time, psTimeType type)
+{
+    double delta = 0.0;
+
+
+    if(time->type == type) {
+        psError(__func__, " : Line %d - Time is already in the correct psTime format. Time type: %d", __LINE__, type);
+        return NULL;
+    }
+
+    delta = psTimeGetTAIDelta(time);
+
+    if(type == PS_TIME_UTC) {
+        time->sec = time->sec - delta;    // User wants UTC time. Remove leapseconds.
+    } else if(type == PS_TIME_TAI) {
+        time->sec = time->sec + delta;    // User wants TAI time. Add leapseconds.
+    } else {
+        psError(__func__, " : Line %d - Invalid psTimeType: %d", __LINE__, type);
+    }
+
+    return time;
+}
+
+double psTimeToLST(psTime *time, double longitude)
+{
+    psF64  jdTdtDays    =  0.0;
+    psF64  jdUt1Days    =  0.0;
+    psF64  mjdUt1Days   =  0.0;
+    psF64  lmstRad      =  0.0;
+    psF64  fracDays     =  0.0;
+    psF64  gmstRad      =  0.0;
+    psF64  t            =  0.0;
+    psF64  tu           =  0.0;
+    psF64  ut1UtcDbl    =  0.0;
+    psF64  const1       =  24110.5493771;
+    psF64  const2       =  8639877.3173760;
+    psF64  const3       =  307.4771600;
+    psF64  const4       =  0.0931118;
+    psF64  const5       = -0.0000062;
+    psF64  const6       =  0.0000013;
+    psTime *ut1UtcDelta = NULL;
+    psTime *tdtDelta    = NULL;
+    psTime *tdtTime     = NULL;
+    psTime *taiTime     = NULL;
+    psTime *utcTime     = NULL;
+    psTime *ut1Time     = NULL;
+
+
+    // Calculate TAI or UTC time based on type of time user passes
+    if(time->type == PS_TIME_TAI) {
+        taiTime = psMemIncrRefCounter(time);
+        ALLOC_TIME(utcTime);
+        utcTime->sec = taiTime->sec - psTimeGetTAIDelta(time);
+        utcTime->usec = taiTime->usec;
+        utcTime->type = PS_TIME_UTC;
+    } else if(time->type == PS_TIME_UTC) {
+        utcTime = psMemIncrRefCounter(time);
+        ALLOC_TIME(taiTime);
+        taiTime->sec = utcTime->sec + psTimeGetTAIDelta(time);
+        taiTime->usec = utcTime->usec;
+        taiTime->type = PS_TIME_TAI;
+    }
+
+    // Convert Universal Time (UTC) to  UT1
+    ALLOC_TIME(ut1UtcDelta);
+    ut1UtcDelta->type = PS_TIME_UTC;
+
+    ut1UtcDbl = psTimeGetUT1Delta(utcTime)*1e6;
+    ut1UtcDelta->usec = (psU32)fabs(ut1UtcDbl);
+    if(ut1UtcDbl<0) {
+        ut1Time = psTimeSubtract(utcTime, ut1UtcDelta);
+    } else {
+        ut1Time = psTimeAdd(utcTime, ut1UtcDelta);
+    }
+
+
+    // Calculate UT1 as Julian Centuries since J2000.0
+    jdUt1Days = psTimeToJD(ut1Time);
+    mjdUt1Days = psTimeToMJD(ut1Time);
+    t = (jdUt1Days - 2451545.0)/36525.0;
+
+    // Calculate Terrestial Dynamical Time (TDT)
+    ALLOC_TIME(tdtDelta);
+    tdtDelta->sec = 32;
+    tdtDelta->usec = 184000;
+    tdtTime = psTimeAdd(taiTime, tdtDelta);
+
+    // Calculate TDT as Julian centuries since J2000.0
+    jdTdtDays = psTimeToJD(tdtTime);
+    tu = (jdTdtDays - 2451545.0)/36525.0;
+
+    // Calculate fractional part of MJD
+    fracDays = fmod(mjdUt1Days, 1.0);
+
+    // Calculate Greenwich Mean Sidereal Time (GMST) in radians. Equation set up to minimize multiplications
+    gmstRad = fracDays*TWOPI+(const1+const2*tu+t*(const3+t*(const4+t*(const5+const6*t))))*S2R;
+
+    // Place GMST between 0 and 2*pi
+    gmstRad = fmod(gmstRad, TWOPI);
+
+    // Calculate Local Mean Sidereal Time (LMST) in radians
+    lmstRad = gmstRad + longitude;
+
+    // Free temporary structs
+    psFree(ut1UtcDelta);
+    psFree(ut1Time);
+    psFree(tdtTime);
+    psFree(tdtDelta);
+    psFree(utcTime);
+    psFree(taiTime);
+
+    return lmstRad;
+}
+
+double psTimeGetUT1Delta(const psTime *time)
+{
+    return lookupSer7Table(time, 6);
+}
+
+struct psSphere* psTimeGetPoleCoords(const psTime* time)
+{
+
+    double x = lookupSer7Table((psTime*)time, 4);
+    double y = lookupSer7Table((psTime*)time, 5);
+
+    struct psSphere* output = psAlloc(sizeof(psSphere));
+    output->r = x * M_PI / 648000.0; // x in arcsec converted to radians, i.e., x/60/60*M_PI/180
+    output->d = y * M_PI / 648000.0;
+
+    return output;
+}
+
+double psTimeGetTAIDelta(const psTime *time)
+{
+    return lookupTaiUtcTable(time);
+}
+
+long psTimeLeapseconds(const psTime *time1, const psTime *time2)
+{
+    long diff = 0;
+
+    // NULL error checks
+    CHECK_NULL_TIME(time1,0);
+    CHECK_NULL_TIME(time2,0);
+
+    diff = abs(psTimeGetTAIDelta((psTime*)time1)-psTimeGetTAIDelta((psTime*)time2));
+
+    return diff;
+}
+
+double psTimeToJD(const psTime *time)
+{
+    double jd = 0.0;
+
+
+    // NULL error check
+    CHECK_NULL_TIME(time,0.0);
+
+    // Julian date conversion
+    if(time->sec < 0) {
+        jd = time->sec / SEC_PER_DAY - time->usec / USEC_PER_DAY + 2440587.5; // psTime earlier than epoch
+    } else {
+        jd = time->sec / SEC_PER_DAY + time->usec / USEC_PER_DAY + 2440587.5; // psTime greater than epoch
+    }
+
+    return jd;
+}
+
+double psTimeToMJD(const psTime *time)
+{
+    double mjd = 0.0;
+
+
+    // NULL error check
+    CHECK_NULL_TIME(time,0.0);
+
+    // Modified Julian date conversion
+    if(time->sec < 0) {
+        mjd = time->sec / SEC_PER_DAY - time->usec / USEC_PER_DAY + 40587.0; // psTime earlier than epoch
+    } else {
+        mjd = time->sec / SEC_PER_DAY + time->usec / USEC_PER_DAY + 40587.0; // psTime greater than epoch
+    }
+
+    return mjd;
+}
+
+char* psTimeToISOTime(const psTime *time)
+{
+    int ms = 0;
+    char *timeString = NULL;
+    char *tempString = NULL;
+    struct tm *tmTime = NULL;
+    time_t sec;
+
+
+    // NULL error check
+    CHECK_NULL_TIME(time,NULL);
+
+    tempString = psAlloc(MAX_TIME_STRING_LENGTH);
+    timeString = psAlloc(MAX_TIME_STRING_LENGTH);
+
+    ms = time->usec / 1000;
+    sec = time->sec;
+
+    // tmTime variable is statically allocated, no need to free
+    tmTime = gmtime(&sec);
+
+    // Converts psTime to YYYY-MM-DDThh:mm:ss.sss in string form
+    if (!strftime(tempString, MAX_TIME_STRING_LENGTH, "%Y-%m-%dT%H:%M:%S", tmTime)) {
+        psError(__func__, " : Line %d - Failed strftime conversion", __LINE__);
+    }
+
+    if (snprintf(timeString, MAX_TIME_STRING_LENGTH, "%s.%3.3dZ", tempString, ms) < 0) {
+        psError(__func__, " : Line %d - Failed snprintf conversion", __LINE__);
+    }
+    psFree(tempString);
+
+    return timeString;
+}
+
+struct timeval psTimeToTimeval(const psTime *time)
+{
+    struct timeval timevalTime;
+
+
+    // NULL error check
+    CHECK_NULL_TIME(time,timevalTime);
+
+    timevalTime.tv_sec = time->sec;
+    timevalTime.tv_usec = time->usec;
+
+    return timevalTime;
+}
+
+struct tm* psTimeToTM(const psTime *time)
+{
+    long cent = 0;
+    long year = 0;
+    long month = 0;
+    long day = 0;
+    long hour = 0;
+    long minute = 0;
+    long seconds = 0;
+    long temp = 0;
+    struct tm* tmTime = NULL;
+
+
+    seconds = time->sec%60;
+    minute = time->sec/60%60;
+    hour = time->sec/3600%24;
+    day = (time->sec+62135596800)/86400;
+
+    // Add 306 days to make relative to Mar 1, 0; also adjust day to be within a range (1..2**28-1) where our
+    // calculations will work with 32bit ints
+    if(day > (pow(2, 28)-307))
+    {
+        temp = (day - 146097+306)/146097+1;         // Avoid overflow if day close to maxint
+        day -= temp * 146097-306;
+    } else if((day += 306 ) <= 0)
+    {
+        temp = -( -day / 146097 + 1);               // Avoid ambiguity in C division of negatives
+        day -= temp * 146097;
+    }
+
+    cent = (day*4-1)/146097;                        // Calc number of centuries day is after 29 Feb of yr 0
+    day -= cent*146097/4;                           // 4 centuries = 146097 days
+    year = (day*4-1)/1461;                          // Calc number of years into the century
+    day -= year*1461/4;                             // Again March-based (4 yrs =\u02dc 146[01] days)
+    month = (day*12+1093)/367;                      // Get the month (3..14 represent March through
+    day -= (month*367-1094)/12;                     // February of following year)
+    year += cent*100+temp*400;                      // Get the real year, which is off by
+
+    // One if month is January or February
+    if(month > 12)
+    {
+        year++;
+        month -= 12;
+    }
+
+    // Allocate output
+    tmTime = (struct tm*)psAlloc(sizeof(struct tm));
+    if (tmTime == NULL)
+    {
+        psAbort(__func__, " : Line %d - Failed to allocate memory", __LINE__);
+    }
+
+    tmTime->tm_year = year - 1900;
+    tmTime->tm_mon = month - 1;
+    tmTime->tm_mday = day + 1;
+    tmTime->tm_hour = hour;
+    tmTime->tm_min = minute;
+    tmTime->tm_sec = seconds;
+    tmTime->tm_isdst = -1;
+
+    return tmTime;
+}
+
+psTime* psTimeFromJD(double time)
+{
+    double days = 0.0;
+    double seconds = 0.0;
+    psTime *outTime = NULL;
+
+
+    // Allocate psTime struct
+    ALLOC_TIME(outTime);
+
+    // Julian date conversion courtesy of Eugene Magnier
+    days = time - 2440587.5;
+    seconds = days * SEC_PER_DAY;
+    if(seconds < 0.0) {
+        outTime->usec = (seconds - (long)seconds) * -1000000.0;  // psTime earlier than epoch
+    } else {
+        outTime->usec = (seconds - (long)seconds) * 1000000.0;   // psTime greater than epoch
+    }
+    outTime->sec = seconds;
+
+    return outTime;
+}
+
+psTime* psTimeFromMJD(double time)
+{
+    double days = 0.0;
+    double seconds = 0.0;
+    psTime *outTime = NULL;
+
+
+    // Allocate psTime struct
+    ALLOC_TIME(outTime);
+
+    // Modified Julian date conversion courtesy of Eugene Magnier
+    days = time - 40587.0;
+    seconds = days * SEC_PER_DAY;
+    if(seconds < 0.0) {
+        outTime->usec = (seconds - (long)seconds) * -1000000.0;  // psTime earlier than epoch
+    } else {
+        outTime->usec = (seconds - (long)seconds) * 1000000.0;   // psTime greater than epoch
+    }
+    outTime->sec = seconds;
+
+    return outTime;
+}
+
+psTime* psTimeFromISOTime(const char *time)
+{
+    char tempString[MAX_TIME_STRING_LENGTH];
+    int month;
+    int day;
+    int year;
+    int hour;
+    int minute;
+    int second;
+    int millisecond;
+    struct tm tmTime;
+    psTime *outTime = NULL;
+
+
+    // Preserve input string by creating duplicate
+    strncpy(tempString, time, MAX_TIME_STRING_LENGTH);
+
+    // Convert YYYY-MM-DDThh:mm:ss.sss in string form to tm time
+    year = atoi(strtok(tempString, "-"));
+    if (year < 0) {
+        psError(__func__, "Years less than 0 not allowed. Value: %d", year);
+        return outTime;
+    }
+
+    month = atoi(strtok(NULL, "-"));
+    if (month < 1 || month > 12) {
+        psError(__func__, "Month must have a value from 1 to 12. Value: %d", month);
+        return outTime;
+    }
+
+    day = atoi(strtok(NULL, "T"));
+    if (day < 1 || day > 31) {
+        psError(__func__, "Day must have a value from 1 to 31. Value: %d", day);
+        return outTime;
+    }
+
+    hour = atoi(strtok(NULL, ":"));
+    if (hour < 0 || hour > 23) {
+        psError(__func__, "Hour must have a value from 0 to 23. Value: %d", hour);
+        return outTime;
+    }
+
+    minute = atoi(strtok(NULL, ":"));
+    if (minute < 0 || minute > 59) {
+        psError(__func__, "Minute must have a value from 0 to 59. Value: %d", minute);
+        return outTime;
+    }
+
+    second = atoi(strtok(NULL, "."));
+    if (second < 0 || second > 59) {
+        psError(__func__, "Second must have a value from 0 to 59. Value: %d", second);
+        return outTime;
+    }
+
+    millisecond = atoi(strtok(NULL, "Z"));
+    if (millisecond < 0 || millisecond > 1000) {
+        psError(__func__, "Millisecond must have a value from 0 to 999. Value: %d", millisecond);
+        return outTime;
+    }
+
+    tmTime.tm_year = year - 1900;
+    tmTime.tm_mon = month - 1;
+    tmTime.tm_mday = day;
+    tmTime.tm_hour = hour;
+    tmTime.tm_min = minute;
+    tmTime.tm_sec = second;
+    tmTime.tm_isdst = -1;
+
+    // Convert tm time to psTime
+    outTime = psTimeFromTM(&tmTime);
+    outTime->usec = millisecond * 1000;
+
+    return outTime;
+}
+
+psTime* psTimeFromTimeval(const struct timeval *time)
+{
+    psTime *outTime = NULL;
+
+
+    // NULL error check
+    CHECK_NULL_TIME(time,NULL);
+
+    // Allocate psTime struct
+    ALLOC_TIME(outTime)
+
+    // Convert to psTime
+    outTime->sec = time->tv_sec;
+    outTime->usec = time->tv_usec;
+
+    return outTime;
+}
+
+psTime* psTimeFromTM(const struct tm* time)
+{
+    long year;
+    long month;
+    long day;
+    long hour;
+    long minute;
+    long seconds;
+    long temp;
+    psTime *outTime = NULL;
+
+    // NULL error check
+    CHECK_NULL_TIME(time,NULL);
+
+    // Allocate psTime struct
+    ALLOC_TIME(outTime);
+
+    // Extract data from TM struct
+    year = time->tm_year + 1900;
+    month = time->tm_mon + 1;
+    day = time->tm_mday;
+    hour = time->tm_hour;
+    minute = time->tm_min;
+    seconds = time->tm_sec;
+
+    // Make month in range 3..14 (treat Jan & Feb as months 13..14 of prev year)
+    if( month <= 2 )
+    {
+        year -= (temp = (14 - month) / 12);
+        month += 12 * temp;
+    } else if(month > 14)
+    {
+        year += (temp = (month - 3) / 12);
+        month -= 12 * temp;
+    }
+
+    // Make year positive
+    if (year < 0 )
+    {
+        day -= 146097 * (temp = (399 - year) / 400);
+        year += 400 * temp;
+    }
+
+    // Add day of month, days of previous 0-11 month period that began w/March, days of previous 0-399 year
+    // period that began w/March of a 400-multiple year), days of any 400-year periods before that, and 306
+    // days to adjust from Mar 1, year 0-relative to Jan 1, year 1-relative. Add hours, minutes, and seconds.
+    day += (month * 367 - 1094) / 12 + year % 100 * 1461 / 4 + (year/100 * 36524 + year/400) - 306;
+    outTime->sec = (((day - 1) * SEC_PER_DAY) - 62135596800) + hour*SEC_PER_HOUR + minute*SEC_PER_MINUTE + seconds;
+
+    // C's TM does not define a microsecond field. Microseconds must be manipulated by calling function.
+    outTime->usec = 0;
+
+    return outTime;
+}
+
+psTime* psTimeAdd(const psTime *tai1, const psTime *tai2)
+{
+    long deltaUsec = 0;
+    psTime *outTime = NULL;
+
+
+    if(tai1->type != tai2->type) {
+        psError(__func__, " : Line %d - Argument types inconsistent for time addition", __LINE__);
+        return NULL;
+    }
+
+    ALLOC_TIME(outTime);
+    outTime->type = tai1->type;
+    outTime->sec = tai1->sec + tai2->sec;
+    deltaUsec = tai1->usec + tai2->usec;
+
+    // Adjust time in case of microsecond overflow after subtraction
+    if(deltaUsec > 1e6) {
+        outTime->sec++;
+        outTime->usec = 2e6 - deltaUsec;
+    } else {
+        outTime->usec = deltaUsec;
+    }
+
+    return outTime;
+}
+
+psTime* psTimeSubtract(const psTime *tai1, const psTime *tai2)
+{
+    long deltaUsec = 0;
+    psTime *outTime = NULL;
+
+
+    if(tai1->type != tai2->type) {
+        psError(__func__, " : Line %d - Argument types inconsistent for time subtraction", __LINE__);
+        return NULL;
+    }
+
+    ALLOC_TIME(outTime);
+    outTime->type = tai1->type;
+    outTime->sec = tai1->sec - tai2->sec;
+    deltaUsec = (long)tai1->usec - (long)tai2->usec;
+
+    // Adjust time in case of microsecond underflow after subtraction
+    if(deltaUsec < 0) {
+        outTime->sec--;
+        outTime->usec = 1e6+deltaUsec;
+    } else {
+        outTime->usec = deltaUsec;
+    }
+
+    return outTime;
+}
+
+psTime* psTimeDelta(const psTime *tai1, const psTime *tai2)
+{
+    long deltaUsec = 0;
+    psTime *outTime = NULL;
+
+
+    if(tai1->type != tai2->type) {
+        psError(__func__, " : Line %d - Argument types inconsistent for time subtraction", __LINE__);
+        return NULL;
+    }
+
+    ALLOC_TIME(outTime);
+    outTime->type = tai1->type;
+    outTime->sec = tai1->sec - tai2->sec;
+    deltaUsec = tai1->usec - tai2->usec;
+
+    // Adjust time in case of microsecond underflow after subtraction
+    if(deltaUsec < 0) {
+        outTime->sec--;
+        outTime->usec = 1e6+deltaUsec;
+    } else {
+        outTime->usec = deltaUsec;
+    }
+
+    outTime->sec = abs(outTime->sec);
+
+    return outTime;
+}
Index: /branches/rel3/psLib/src/astro/psTime.h
===================================================================
--- /branches/rel3/psLib/src/astro/psTime.h	(revision 2163)
+++ /branches/rel3/psLib/src/astro/psTime.h	(revision 2163)
@@ -0,0 +1,315 @@
+/** @file  psTime.h
+ *
+ *  @brief Definitions for time, time utilities, and conversion functions for use with psLib astronomy
+ *  functions.
+ *
+ *  A collection of functions are required by psLib to manipulate time data. These functions primarily consist
+ *  of conversions between specific time formats.  PSLib currently uses the UNIX timeval time system as the
+ *  base upon which International Atomic Time (TAI) and Universal Time Coordinated (UTC) are calculated. TAI
+ *  time varies over time due to the earth's rotation and the movement of the continental plates. It is
+ *  currentls 32 seconds faster than UTC/timeval time. The conversion between TAI and UTC time for other dates
+ *  is given in the table below, which comes from:
+ *
+ *  ftp://maia.usno.navy.mil/ser7/tai-utc.dat
+ *
+ *  This table is placed into a static array and used by the psTime functions for conversions.
+ *
+ *   1961 JAN  1 =JD 2437300.5  TAI-UTC=   1.4228180 S + (MJD - 37300.) X 0.001296 S
+ *   1961 AUG  1 =JD 2437512.5  TAI-UTC=   1.3728180 S + (MJD - 37300.) X 0.001296 S
+ *   1962 JAN  1 =JD 2437665.5  TAI-UTC=   1.8458580 S + (MJD - 37665.) X 0.0011232S
+ *   1963 NOV  1 =JD 2438334.5  TAI-UTC=   1.9458580 S + (MJD - 37665.) X 0.0011232S
+ *   1964 JAN  1 =JD 2438395.5  TAI-UTC=   3.2401300 S + (MJD - 38761.) X 0.001296 S
+ *   1964 APR  1 =JD 2438486.5  TAI-UTC=   3.3401300 S + (MJD - 38761.) X 0.001296 S
+ *   1964 SEP  1 =JD 2438639.5  TAI-UTC=   3.4401300 S + (MJD - 38761.) X 0.001296 S
+ *   1965 JAN  1 =JD 2438761.5  TAI-UTC=   3.5401300 S + (MJD - 38761.) X 0.001296 S
+ *   1965 MAR  1 =JD 2438820.5  TAI-UTC=   3.6401300 S + (MJD - 38761.) X 0.001296 S
+ *   1965 JUL  1 =JD 2438942.5  TAI-UTC=   3.7401300 S + (MJD - 38761.) X 0.001296 S
+ *   1965 SEP  1 =JD 2439004.5  TAI-UTC=   3.8401300 S + (MJD - 38761.) X 0.001296 S
+ *   1966 JAN  1 =JD 2439126.5  TAI-UTC=   4.3131700 S + (MJD - 39126.) X 0.002592 S
+ *   1968 FEB  1 =JD 2439887.5  TAI-UTC=   4.2131700 S + (MJD - 39126.) X 0.002592 S
+ *   1972 JAN  1 =JD 2441317.5  TAI-UTC=  10.0       S + (MJD - 41317.) X 0.0      S
+ *   1972 JUL  1 =JD 2441499.5  TAI-UTC=  11.0       S + (MJD - 41317.) X 0.0      S
+ *   1973 JAN  1 =JD 2441683.5  TAI-UTC=  12.0       S + (MJD - 41317.) X 0.0      S
+ *   1974 JAN  1 =JD 2442048.5  TAI-UTC=  13.0       S + (MJD - 41317.) X 0.0      S
+ *   1975 JAN  1 =JD 2442413.5  TAI-UTC=  14.0       S + (MJD - 41317.) X 0.0      S
+ *   1976 JAN  1 =JD 2442778.5  TAI-UTC=  15.0       S + (MJD - 41317.) X 0.0      S
+ *   1977 JAN  1 =JD 2443144.5  TAI-UTC=  16.0       S + (MJD - 41317.) X 0.0      S
+ *   1978 JAN  1 =JD 2443509.5  TAI-UTC=  17.0       S + (MJD - 41317.) X 0.0      S
+ *   1979 JAN  1 =JD 2443874.5  TAI-UTC=  18.0       S + (MJD - 41317.) X 0.0      S
+ *   1980 JAN  1 =JD 2444239.5  TAI-UTC=  19.0       S + (MJD - 41317.) X 0.0      S
+ *   1981 JUL  1 =JD 2444786.5  TAI-UTC=  20.0       S + (MJD - 41317.) X 0.0      S
+ *   1982 JUL  1 =JD 2445151.5  TAI-UTC=  21.0       S + (MJD - 41317.) X 0.0      S
+ *   1983 JUL  1 =JD 2445516.5  TAI-UTC=  22.0       S + (MJD - 41317.) X 0.0      S
+ *   1985 JUL  1 =JD 2446247.5  TAI-UTC=  23.0       S + (MJD - 41317.) X 0.0      S
+ *   1988 JAN  1 =JD 2447161.5  TAI-UTC=  24.0       S + (MJD - 41317.) X 0.0      S
+ *   1990 JAN  1 =JD 2447892.5  TAI-UTC=  25.0       S + (MJD - 41317.) X 0.0      S
+ *   1991 JAN  1 =JD 2448257.5  TAI-UTC=  26.0       S + (MJD - 41317.) X 0.0      S
+ *   1992 JUL  1 =JD 2448804.5  TAI-UTC=  27.0       S + (MJD - 41317.) X 0.0      S
+ *   1993 JUL  1 =JD 2449169.5  TAI-UTC=  28.0       S + (MJD - 41317.) X 0.0      S
+ *   1994 JUL  1 =JD 2449534.5  TAI-UTC=  29.0       S + (MJD - 41317.) X 0.0      S
+ *   1996 JAN  1 =JD 2450083.5  TAI-UTC=  30.0       S + (MJD - 41317.) X 0.0      S
+ *   1997 JUL  1 =JD 2450630.5  TAI-UTC=  31.0       S + (MJD - 41317.) X 0.0      S
+ *   1999 JAN  1 =JD 2451179.5  TAI-UTC=  32.0       S + (MJD - 41317.) X 0.0      S
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-12 01:34:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PSTIME_H
+#define PSTIME_H
+
+#include <time.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include "psType.h"
+#include "psImage.h"
+
+struct psSphere;
+
+/// @addtogroup Time
+/// @{
+
+
+/** Time type.
+ *
+ * Enumeration for psTime types, TAI or UTC time.
+ */
+typedef enum {
+    PS_TIME_TAI,        ///< Temps Atomique International (TAI) time (time with leapseconds).
+    PS_TIME_UTC,        ///< Universal Time Coordinated (UTC) time (time without leapseconds).
+} psTimeType;
+
+/** Definition of psTime.
+ *
+ *  The psTime struct is used by psLib to represent time values critical to
+ *  astronomical calculations.  This structure represents a time which is
+ *  equivalent to TAI (International Atomic Time) and is measured in both
+ *  seconds and microseconds.
+ */
+typedef struct psTime
+{
+    psS64 sec;                          ///< Seconds since epoch, Jan 1, 1970.
+    psU32 usec;                         ///< Microseconds since last second.
+    psTimeType type;                    ///< Type of time.
+}
+psTime;
+
+/** Get current time.
+ *
+ * Gets current time from the system clock. User must specify the psTimeType (PS_TIME_TAI or PS_TIME_UTC) in
+ * the argument.
+ *
+ *  @return  psTime*: Struct with current time.
+ */
+psTime* psTimeGetTime(
+    psTimeType type                     ///< Type of time to get (UTC or TAI).
+);
+
+/** Convert psTime to UTC or TAI time.
+ *
+ *  Converts psTime to UTC or TAI time based on the psTimeType argument.
+ *
+ *  @return  psTime*: Pointer to psTime.
+ */
+psTime* psTimeConvert(
+    psTime *time,                       ///< Time to be converted.
+    psTimeType type                     ///< Type to be converted to.
+);
+
+/** Convert psTime to Local Mean Sidereal Time (LST).
+ *
+ *  Converts psTime at the given longitude to LST time. If the input time is not in UTC format, then it is
+ *  converted.
+ *
+ *  @return  double: LST Time.
+ */
+double psTimeToLST(
+    psTime *time,                       ///< psTime to be converted.
+    double longitude                    ///< Longitude.
+);
+
+/** Determine UT1 - UTC from table lookup.
+ *
+ *  This function is necessary to for various SLALIB functions.
+ *
+ *  @return  double: Time difference.
+ */
+double psTimeGetUT1Delta(
+    const psTime *time                  ///< psTime to be looked up.
+);
+
+/** Determine TAI - UTC from table lookup.
+ *
+ *  This function is necessary to for various psTime functions.
+ *
+ *  @return  double: Time difference.
+ */
+double psTimeGetTAIDelta(
+    const psTime *time                  ///< psTime to be looked up.
+);
+
+/** Determine polar coordinates at a given time.
+ *
+ *  Determines the orientation of the polar axis at the given time.
+ *
+ *  @return  psSphere*: Spherical coordinates of Earth's polar axias.
+ */
+struct psSphere* psTimeGetPoleCoords(
+                const psTime *time                  ///< psTime determine polar orientation.
+            );
+
+/** Calculate the number of leapseconds between two times.
+ *
+ *  Calculates the number of leapseconds between two times.
+ *
+ *  @return  long: leapseconds added between given times
+ */
+long psTimeLeapseconds(
+    const psTime* time1,                ///< First input time.
+    const psTime* time2                 ///< Second input time.
+);
+
+/** Convert psTime to Julian date time.
+ *
+ *  Converts psTime to Julian date (JD) time. This function does not add or subtract leapseconds.
+ *
+ *  @return  double: Julian Date (JD) time.
+ */
+double psTimeToJD(
+    const psTime* time                  ///< Input time to be converted.
+);
+/** Convert psTime to modified Julian date time.
+ *
+ *  Converts psTime to modified Julian date (MJD) time. This function does not add or subtract leapseconds.
+ *
+ *  @return  double: Modified Julian Days (MJD) time.
+ */
+double psTimeToMJD(
+    const psTime* time                  ///< Input time to be converted.
+);
+
+/** Convert psTime to ISO8601 formatted string.
+ *
+ *  Converts psTime to a null terminated string in the form of YYYY-MM-DDThh:mm:ss.sss. This function does not
+ *  add or subtract leapseconds.
+ *
+ *  @return  char*: Pointer null terminated array of chars in ISO time.
+ */
+char* psTimeToISOTime(
+    const psTime* time                  ///< Input time to be converted.
+);
+
+/** Convert psTime to timeval time.
+ *
+ *  Converts psTime to timeval time. This function does not add or subtract leapseconds.
+ *
+ *  @return  timeval: timeval struct time.
+ */
+struct timeval psTimeToTimeval(
+                const psTime* time                  ///< Input time to be converted.
+            );
+
+/** Convert psTime to tm time.
+ *
+ * Converts psTime to tm time. This function is based on a Perl algorithm availble in the Pan-STARRS Image
+ * processing Algorithm Design Description (ADD). This function does not add or subtract leapseconds.
+ *
+ *  @return  tm: tm struct time.
+ */
+struct tm* psTimeToTM(
+                const psTime *time                  ///< Input time to be converted.
+            );
+
+/** Convert JD to psTime.
+ *
+ *  Converts JD time to psTime. This function does not add or subtract leapseconds.
+ *
+ *  @return  psTime: time.
+ */
+psTime* psTimeFromJD(
+    double time                         ///< Input time to be converted.
+);
+
+/** Convert MJD to psTime.
+ *
+ *  Converts MJD time to psTime. This function does not add or subtract leapseconds.
+ *
+ *  @return  psTime: time.
+ */
+psTime* psTimeFromMJD(
+    double time                         ///< Input time to be converted.
+);
+
+/** Convert ISO to psTime.
+ *
+ *  Converts ISO time to psTime. This function does not add or subtract leapseconds.
+ *
+ *  @return  psTime*: time
+ */
+psTime* psTimeFromISOTime(
+    const char* time                    ///< Input time to be converted.
+);
+
+/** Convert timeval to psTime.
+ *
+ *  Converts timeval time to psTime. This function does not add or subtract leapseconds.
+ *
+ *  @return  psTime*: time.
+ */
+psTime* psTimeFromTimeval(
+    const struct timeval *time          ///< Input time to be converted.
+);
+
+/** Convert tm time to psTime.
+ *
+ *  Converts tm time to psTime. This function is based on a Perl algorithm availble in the Pan-STARRS Image
+ * processing Algorithm Design Description (ADD). This function does not add or subtract leapseconds.
+ *
+ *  @return  psTime*: time.
+ */
+psTime* psTimeFromTM(
+    const struct tm *time               ///< Input time to be converted.
+);
+
+/** Add two TAI times.
+ *
+ *  Adds two TAI times. This function does not add or subtract leapseconds.
+ *
+ *  @return  psTime*: time.
+ */
+psTime* psTimeAdd(
+    const psTime *tai1,                 ///< First TAI time.
+    const psTime *tai2                  ///< Second TAI time.
+);
+
+/** Subtract two TAI times.
+ *
+ *  Subtracts two TAI times. This function does not add or subtract leapseconds.
+ *
+ *  @return  psTime*: time.
+ */
+psTime* psTimeSubtract(
+    const psTime *tai1,                 ///< First TAI time.
+    const psTime *tai2                  ///< Second TAI time.
+);
+
+
+/** Find delta of two TAI times.
+ *
+ *  Finds the absolute difference of two TAI times. This function does not add or subtract leapseconds.
+ *
+ *  @return  psTime*: time.
+ */
+psTime* psTimeDelta(
+    const psTime *tai1,                 ///< First TAI time.
+    const psTime *tai2                  ///< Second TAI time.
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/astronomy/Makefile
===================================================================
--- /branches/rel3/psLib/src/astronomy/Makefile	(revision 2163)
+++ /branches/rel3/psLib/src/astronomy/Makefile	(revision 2163)
@@ -0,0 +1,63 @@
+ifndef prefix
+    export prefix=$(shell cd ../..;pwd)
+endif
+
+TARGET_STATIC  = libpslib.a
+include ../Makefile.Globals
+CFLAGS := $(CFLAGS_RELOC) -I. -I../sysUtils -I../collections -I../dataManip \
+    -I.. -I../image -DSER7_FILE="\"$(SER7_FILE)\"" -DTAIUTC_FILE="\"$(TAIUTC_FILE)\""
+
+SRC_OBJS = psTime.o \
+           psMetadata.o \
+           psMetadataIO.o \
+           psCoord.o \
+           psAstrometry.o
+
+OBJS = $(addprefix makedir/,$(SRC_OBJS))
+
+HEADERS = $(SRC_OBJS:.o=.h) psPhotometry.h slalib.h
+
+all: $(TARGET_STATIC)
+
+psAstronomyErrors.h: psAstronomyErrors.dat
+	perl ../parseErrorCodes.pl --data=$? $@
+
+
+# Rule to make static library
+
+libpslib.a:     $(OBJS)
+# The ar option -r is to add/replace object and -s is to create
+# a symbol table in the archive
+	$(AR) rcs ../$@ $(OBJS)
+
+# Define PHONY target "install" which will install necessary files
+install: $(TARGET_STATIC)
+	install $(HEADERS) $(includedir)
+
+# Define PHONY target "distclean" which will cleanup the distribution
+distclean:      clean
+	$(RM) ../$(TARGET_STATIC)
+
+# Define PHONY target "clean" which will cleanup the development area
+clean:
+	@echo "    Deleting intermediate files for 'astronomy'"
+	$(RM) $(OBJS) *.lint $(SRC_OBJS:.o=.i)
+
+cleandep:
+	$(RM) $(OBJS:.o=.d)
+
+%.lint: %.c
+	splint +posixlib -exportlocal -realcompare $(INCLUDE_GLOBAL) $? > $@; cat $@
+
+%.i: %.c
+	$(CC) -E $(CFLAGS) -o $@ $<
+
+makedir/%.o: %.c
+	$(CC) -c $(CFLAGS) -o $@ $<
+
+makedir/%.d: %.c
+	$(CC) -MM $(CFLAGS) $< > $@.tmp
+	sed 's|\($*\)\.o[ :]*|\1.o $@ : |g' $@.tmp > $@
+	$(RM) -f $@.tmp
+
+include $(OBJS:.o=.d)
Index: /branches/rel3/psLib/src/astronomy/psAstrometry.c
===================================================================
--- /branches/rel3/psLib/src/astronomy/psAstrometry.c	(revision 2163)
+++ /branches/rel3/psLib/src/astronomy/psAstrometry.c	(revision 2163)
@@ -0,0 +1,847 @@
+/** @file  psAstrometry.c
+ *
+ *  @brief This file defines the basic types for astronomical coordinate
+ *  transformation
+ *
+ *  @ingroup AstroImage
+ *
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.42 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 23:45:53 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include <string.h>
+#include <math.h>
+
+#include "psFunctions.h"
+#include "psAstrometry.h"
+#include "psMemory.h"
+#include "psAbort.h"
+#include "psError.h"
+#include "psConstants.h"
+#include "slalib.h"
+
+/*****************************************************************************
+checkValidImageCoords(): this is a private function which simply
+determines if the supplied x,y coordinates are in the range for the supplied
+psImage.
+ *****************************************************************************/
+static int checkValidImageCoords(double x,
+                                 double y,
+                                 psImage* tmpImage)
+{
+    if (tmpImage == NULL) {
+        return(0);
+    }
+
+    if ((x < 0.0) ||
+            (x > (double)tmpImage->numCols) ||
+            (y < 0.0) ||
+            (y > (double)tmpImage->numRows)) {
+        return (0);
+    }
+
+    return (1);
+}
+
+/*****************************************************************************
+isProjectionLinear(): this is a private function which simply determines
+if the supplied psPlaneTransform transform is linear: if any of the
+cooefficients of order 2 are higher are non-zero, then it is not linear.
+ *****************************************************************************/
+static int isProjectionLinear(psPlaneTransform *transform)
+{
+    int i = 0;
+    PS_CHECK_NULL_PTR_RETURN_ZERO(transform);
+
+    for (i=2;i<(transform->x->nX);i++) {
+        if (transform->x->coeff[i][0] != 0.0) {
+            return(0);
+        }
+    }
+    for (i=2;i<(transform->x->nY);i++) {
+        if (transform->x->coeff[0][i] != 0.0) {
+            return(0);
+        }
+    }
+
+    for (i=2;i<(transform->y->nX);i++) {
+        if (transform->y->coeff[i][0] != 0.0) {
+            return(0);
+        }
+    }
+    for (i=2;i<(transform->y->nY);i++) {
+        if (transform->y->coeff[0][i] != 0.0) {
+            return(0);
+        }
+    }
+
+    return(1);
+}
+
+/*****************************************************************************
+invertPlaneTransform(transform): : this is a private function which
+simply inverts the supplied psPlaneTransform transform.  It assumes that
+"transform" is linear.
+ 
+This program assumes that the inverse of the following linear equations:
+        X2 = A + (B * X1) + (C * Y1);
+        Y2 = D + (E * X1) + (F * Y1);
+is
+        Y1 = (Y2 - ((E/B) * X2) - D + ((E*A)/B)) / (F - ((C*E)/B));
+        X1 = (Y2 - ((F/C) * X2) - D + ((F*A)/C)) / (E - ((F*B)/C));
+or
+ X1 = (-D + ((F*A)/C)) / (E - ((F*B)/C)) +
+      (X2 * -((F/C) / (E - ((F*B)/C)))) +
+             (Y2 * (1.0 / (E - ((F*B)/C))));
+        Y1 = (-D + ((E*A)/B))/(F - ((C*E)/B)) +
+             (X2 * -((E/B) / (F - ((C*E)/B)))) +
+             (Y2 * (1.0 / (F - ((C*E)/B))));
+ *****************************************************************************/
+static psPlaneTransform *invertPlaneTransform(psPlaneTransform *transform)
+{
+    double A = transform->x->coeff[0][0];
+    double B = transform->x->coeff[1][0];
+    double C = transform->x->coeff[0][1];
+    double D = transform->y->coeff[0][0];
+    double E = transform->y->coeff[1][0];
+    double F = transform->y->coeff[0][1];
+
+    PS_CHECK_NULL_PTR_RETURN_NULL(transform);
+    psPlaneTransform *out = psAlloc(sizeof(psPlaneTransform));
+
+    out->x->coeff[0][0] = -D + ((F*A)/C) / (E - ((F*B)/C));
+    out->x->coeff[1][0] = -(F/C) / (E - ((F*B)/C));
+    out->x->coeff[0][1] =  1.0 / (E - ((F*B)/C));
+    out->y->coeff[0][0] = -D + ((E*A)/B) / (F - ((C*E)/B));
+    out->y->coeff[1][0] = -(E/B) / (F - ((C*E)/B));
+    out->y->coeff[0][1] =  1.0 / (F - ((C*E)/B));
+
+    return(out);
+}
+
+static void FPAFree(psFPA* fpa)
+{
+    if (fpa != NULL) {
+        psFree(fpa->chips);
+        psFree(fpa->grommit);
+        psFree((psExposure*)fpa->exposure);
+        psFree(fpa->metadata);
+        psFree(fpa->fromTangentPlane);
+        psFree(fpa->toTangentPlane);
+        psFree(fpa->pattern);
+        psFree(fpa->colorPlus);
+        psFree(fpa->colorMinus);
+        psFree(fpa->projection);
+    }
+}
+
+static void chipFree(psChip* chip)
+{
+    if (chip != NULL) {
+        psFree(chip->cells);
+        psFree(chip->metadata);
+        psFree(chip->toFPA);
+        psFree(chip->fromFPA);
+    }
+}
+
+static void cellFree(psCell* cell)
+{
+    if (cell != NULL) {
+        psFree(cell->readouts);
+        psFree(cell->metadata);
+        psFree(cell->toChip);
+        psFree(cell->fromChip);
+        psFree(cell->toFPA);
+        psFree(cell->toTP);
+    }
+}
+
+static void readoutFree(psReadout* readout)
+{
+    if (readout != NULL) {
+        psFree(readout->image);
+        psFree(readout->mask);
+        psFree(readout->objects);
+        psFree(readout->metadata);
+    }
+}
+
+static void observatoryFree(psObservatory* obs)
+{
+    if (obs != NULL) {
+        psFree((void*)obs->name);
+    }
+}
+
+static void exposureFree(psExposure* exp)
+{
+    if (exp != NULL) {
+        psFree((void*)exp->time);
+        psFree((void*)exp->observatory);
+        psFree((void*)exp->cameraName);
+        psFree((void*)exp->telescopeName);
+    }
+}
+
+static void fixedPatternFree(psFixedPattern* fp)
+{
+    if (fp != NULL) {
+        for (int i = 0; i < fp->p_ps_xRows; i++) {
+            psFree(fp->x[i]);
+        }
+
+        for (int j = 0; j < fp->p_ps_yRows; j++) {
+            psFree(fp->y[j]);
+        }
+
+        psFree(fp->x);
+        psFree(fp->y);
+    }
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+
+/*
+ * XXX: Verify that you interpreted the SDR correctly.
+ *
+ * XXX: This assumes that x,y must be of type F64
+ */
+psFixedPattern* psFixedPatternAlloc(double x0,
+                                    double y0,
+                                    double xScale,
+                                    double yScale,
+                                    const psImage *x,
+                                    const psImage *y)
+{
+    psFixedPattern *tmp;
+    int i;
+    int j;
+
+    PS_CHECK_NULL_IMAGE_RETURN_NULL(x);
+    PS_CHECK_NULL_IMAGE_RETURN_NULL(y);
+    PS_CHECK_IMAGE_TYPE_RETURN_NULL(x, PS_TYPE_F64);
+    PS_CHECK_IMAGE_TYPE_RETURN_NULL(y, PS_TYPE_F64);
+
+    tmp = (psFixedPattern *) psAlloc(sizeof(psFixedPattern));
+    // XXX: Is this correct?
+    tmp->nX = (x->numCols * x->numRows);
+    tmp->nY = (y->numCols * y->numRows);
+    tmp->x0 = x0;
+    tmp->y0 = y0;
+    tmp->xScale = xScale;
+    tmp->yScale = yScale;
+    tmp->p_ps_xRows = x->numRows;
+    tmp->p_ps_xCols = x->numCols;
+    tmp->p_ps_yRows = y->numRows;
+    tmp->p_ps_yCols = y->numCols;
+    tmp->x = (double **) psAlloc(x->numRows * sizeof(double *));
+    for (i=0;i<x->numRows;i++) {
+        (tmp->x)[i] = (double *) psAlloc(x->numCols * sizeof(double));
+    }
+    for (i=0;i<x->numRows;i++) {
+        for (j=0;j<x->numCols;j++) {
+            (tmp->x)[i][j] = x->data.F64[i][j];
+        }
+    }
+
+    tmp->y = (double **) psAlloc(y->numRows * sizeof(double *));
+    for (i=0;i<y->numRows;i++) {
+        (tmp->y)[i] = (double *) psAlloc(y->numCols * sizeof(double));
+    }
+    for (i=0;i<y->numRows;i++) {
+        for (j=0;j<y->numCols;j++) {
+            (tmp->y)[i][j] = y->data.F64[i][j];
+        }
+    }
+
+    p_psMemSetDeallocator(tmp,(psFreeFcn)fixedPatternFree);
+
+    return(tmp);
+}
+
+
+psExposure* psExposureAlloc(double ra,
+                            double dec,
+                            double hourAngle,
+                            double zenithDistance,
+                            double azimuth,
+                            const psTime* time,
+                            float rotAngle,
+                            float temperature,
+                            float pressure,
+                            float humidity,
+                            float exposureTime,
+                            float wavelength,
+                            const psObservatory* observatory)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(observatory);
+    psExposure* exp = psAlloc(sizeof(psExposure));
+
+    *(double *)&exp->ra = ra;
+    *(double *)&exp->dec = dec;
+    *(double *)&exp->hourAngle = hourAngle;
+    *(double *)&exp->zenithDistance = zenithDistance;
+    *(double *)&exp->azimuth = azimuth;
+    *(float *)&exp->rotAngle = rotAngle;
+    *(float *)&exp->temperature = temperature;
+    *(float *)&exp->pressure = pressure;
+    *(float *)&exp->humidity = humidity;
+    *(float *)&exp->exposureTime = exposureTime;
+    *(float *)&exp->wavelength = wavelength;
+
+    exp->time = psMemIncrRefCounter((void*)time);
+    exp->observatory = psMemIncrRefCounter((void*)observatory);
+
+    // XXX: how is these value derived?
+    *(double *)&exp->lst = psTimeToLST((psTime*)time,observatory->longitude);
+    *(float *)&exp->positionAngle = 0.0f; // XXX: need input, see Bug #207
+    *(float *)&exp->parallacticAngle = 0.0f; // XXX: need input, see Bug #207
+    *(float *)&exp->airmass = slaAirmas(zenithDistance);
+    *(float *)&exp->parallacticFactor = 0.0f;
+    exp->cameraName = NULL;
+    exp->telescopeName = NULL;
+
+    p_psMemSetDeallocator(exp,(psFreeFcn)exposureFree);
+
+    return exp;
+}
+
+psObservatory* psObservatoryAlloc(const char* name,
+                                  double latitude,
+                                  double longitude,
+                                  double height,
+                                  double tlr)
+{
+    psObservatory* obs = psAlloc(sizeof(psObservatory));
+
+    if (name == NULL) {
+        obs->name = NULL;
+    } else {
+        obs->name = psAlloc(strlen(name)+1);
+        strcpy((char*)obs->name, name);
+    }
+
+    *(double *)&obs->latitude = latitude;
+    *(double *)&obs->longitude = longitude;
+    *(double *)&obs->height = height;
+    *(double *)&obs->tlr = tlr;
+
+    p_psMemSetDeallocator(obs,(psFreeFcn)observatoryFree);
+
+    return obs;
+}
+
+psFPA* psFPAAlloc(int nChips,
+                  const psExposure* exp)
+{
+    psFPA* newFPA = psAlloc(sizeof(psFPA));
+
+    // create array of NULL chips of the size nChips
+    newFPA->chips = psArrayAlloc(nChips);
+    void** chips = newFPA->chips->data;
+    for (int i=0;i<nChips;i++) {
+        chips[i] = NULL;
+    }
+
+    newFPA->metadata = NULL;
+    newFPA->fromTangentPlane = NULL;
+    newFPA->toTangentPlane = NULL;
+    newFPA->pattern = NULL;
+
+    if (exp != NULL) {
+        newFPA->exposure = psMemIncrRefCounter((psExposure*)exp);
+        newFPA->grommit = psGrommitAlloc(exp);
+    } else {
+        newFPA->exposure = NULL;
+        newFPA->grommit = NULL;
+    }
+
+    newFPA->colorPlus = NULL;
+    newFPA->colorMinus = NULL;
+    newFPA->projection = NULL;
+
+    newFPA->rmsX = 0.0f;
+    newFPA->rmsY = 0.0f;
+    newFPA->chi2 = 0.0f;
+
+    p_psMemSetDeallocator(newFPA,(psFreeFcn)FPAFree);
+
+    return newFPA;
+}
+
+/*
+ * psChip constructor
+ */
+psChip* psChipAlloc(int nCells,
+                    psFPA *parentFPA)
+{
+    psChip* chip = psAlloc(sizeof(psChip));
+
+    // create array of NULL psCells
+    chip->cells = psArrayAlloc(nCells);
+    void** cells = chip->cells->data;
+    for (int i=0;i<nCells;i++) {
+        cells[i] = NULL;
+    }
+
+    chip->metadata = NULL;
+
+    chip->toFPA = NULL;
+    chip->fromFPA = NULL;
+
+    chip->parent = parentFPA;
+
+    p_psMemSetDeallocator(chip,(psFreeFcn)chipFree);
+
+    return chip;
+
+}
+
+/*
+ * psCell constructor
+ */
+psCell* psCellAlloc(int nReadouts,
+                    psChip* parentChip)
+{
+    psCell* cell = psAlloc(sizeof(psCell));
+
+    // create array of NULL psReadouts
+    cell->readouts = psArrayAlloc(nReadouts);
+    void** readouts = cell->readouts->data;
+    for (int i=0;i<nReadouts;i++) {
+        readouts[i] = NULL;
+    }
+
+    cell->metadata = NULL;
+
+    cell->toChip = NULL;
+    cell->fromChip = NULL;
+    cell->toFPA = NULL;
+    cell->toTP = NULL;
+
+    cell->parent = parentChip;
+
+    p_psMemSetDeallocator(cell,(psFreeFcn)cellFree);
+
+    return cell;
+
+
+}
+
+psReadout* psReadoutAlloc(int col0,
+                          int row0,
+                          const psImage* image)
+{
+    psReadout* readout = psAlloc(sizeof(psReadout));
+
+    *(unsigned int*)&readout->colBins = 1;
+    *(unsigned int*)&readout->rowBins = 1;
+    *(int*)&readout->col0 = col0;
+    *(int*)&readout->row0 = row0;
+
+    readout->image = (psImage*)image;
+    readout->mask = NULL;
+    readout->objects = NULL;
+    readout->metadata = NULL;
+
+    p_psMemSetDeallocator(readout,(psFreeFcn)readoutFree);
+
+    return readout;
+}
+
+psGrommit* psGrommitAlloc(const psExposure* exp)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(exp);
+
+    double date = psTimeToMJD(exp->time);
+    double dut = psTimeGetUT1Delta(exp->time);
+    double elongm = exp->observatory->longitude;
+    double phim = exp->observatory->latitude;
+    double hm = exp->observatory->height;
+
+    psSphere* polarMotion = psTimeGetPoleCoords(exp->time);
+    double xp = polarMotion->r;
+    double yp = polarMotion->d;
+    psFree(polarMotion);
+
+    double tdk = exp->temperature;
+    double pmb = exp->pressure;
+    double rh = exp->humidity;
+    double wl = exp->wavelength;
+    double tlr = exp->observatory->tlr;
+
+    psGrommit* grommit = (psGrommit* ) psAlloc(sizeof(psGrommit));
+
+    slaAoppa(date, dut, elongm, phim, hm, xp, yp,
+             tdk, pmb, rh, wl, tlr, (double*)grommit);
+
+    return (grommit);
+}
+
+psCell* psCellInFPA(const psPlane* fpaCoord,
+                    const psFPA* FPA)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(fpaCoord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(FPA);
+    psChip* tmpChip = NULL;
+    psPlane chipCoord;
+    psCell* outCell = NULL;
+
+    // Determine which chip contains the fpaCoords.
+    tmpChip = psChipInFPA(fpaCoord, FPA);
+    if (tmpChip == NULL) {
+        return(NULL);
+    }
+
+    // Convert to those chip coordinates.
+    psCoordFPAToChip(&chipCoord, fpaCoord, tmpChip);
+
+    // Determine which cell contains those chip coordinates.
+    outCell = psCellInChip(&chipCoord, tmpChip);
+
+    return (outCell);
+}
+
+psChip* psChipInFPA(const psPlane* fpaCoord,
+                    const psFPA* FPA)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(fpaCoord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(FPA);
+    PS_CHECK_NULL_PTR_RETURN_NULL(FPA->chips);
+    psArray* chips = FPA->chips;
+    int nChips = chips->n;
+    psPlane chipCoord;
+    psCell *tmpCell = NULL;
+
+    // Loop through every chip in this FPA.  Convert the original FPA
+    // coordinates to chip coordinates for that chip.  Then, determine if any
+    // cells in that chip contain those chip coordinates.
+
+    for (int i = 0; i < nChips; i++) {
+        psChip* tmpChip = chips->data[i];
+        psPlaneTransformApply(&chipCoord, tmpChip->fromFPA, fpaCoord);
+
+        tmpCell = psCellInChip(&chipCoord, tmpChip);
+        if (tmpCell != NULL) {
+            return(tmpChip);
+        }
+    }
+
+    return (NULL);
+}
+
+psCell* psCellInChip(const psPlane* chipCoord,
+                     const psChip* chip)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(chipCoord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(chip);
+
+    psPlane cellCoord;
+    psArray* cells;
+
+    cells = chip->cells;
+    if (cells == NULL) {
+        return NULL;
+    }
+
+    // We loop over each cell in the chip.  We transform the chipCoord into
+    // a cellCoord for that cell and determine if that cellCoord is valid.
+    // If so, then we return that cell.
+
+    for (int i = 0; i < cells->n; i++) {
+        psCell* tmpCell = (psCell* ) cells->data[i];
+        psArray* readouts = tmpCell->readouts;
+
+        if (readouts != NULL) {
+            for (int j = 0; j < readouts->n; j++) {
+                psReadout* tmpReadout = readouts->data[j];
+
+                psPlaneTransformApply(&cellCoord,
+                                      tmpCell->fromChip,
+                                      chipCoord);
+
+                if (checkValidImageCoords(cellCoord.x,
+                                          cellCoord.y,
+                                          tmpReadout->image)) {
+                    return (tmpCell);
+                }
+            }
+        }
+    }
+
+    return (NULL);
+}
+
+psPlane* psCoordCellToChip(psPlane* outCoord,
+                           const psPlane* inCoord,
+                           const psCell* cell)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(inCoord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(cell);
+
+    return (psPlaneTransformApply(outCoord, cell->toChip, inCoord));
+}
+
+psPlane* psCoordChipToFPA(psPlane* outCoord,
+                          const psPlane* inCoord,
+                          const psChip* chip)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(inCoord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(chip);
+
+    return (psPlaneTransformApply(outCoord, chip->toFPA, inCoord));
+}
+
+psPlane* psCoordFPAToTP(psPlane* outCoord,
+                        const psPlane* inCoord,
+                        double color,
+                        double magnitude,
+                        const psFPA* fpa)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(inCoord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(fpa);
+
+    return(psPlaneDistortApply(outCoord, fpa->toTangentPlane, inCoord,
+                               color, magnitude));
+}
+
+/*****************************************************************************
+XXX: What about units for the (x,y) coords?
+ *****************************************************************************/
+psSphere* psCoordTPToSky(psSphere* outSphere,
+                         const psPlane* tpCoord,
+                         const psGrommit* grommit)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(tpCoord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(grommit);
+
+    double AOB = 0.0;
+    double ZOB = 0.0;
+    double HOB = 0.0;
+    if (outSphere == NULL) {
+        outSphere = (psSphere* ) psAlloc(sizeof(psSphere));
+    }
+
+    slaAopqk(tpCoord->x, tpCoord->y, (double*)grommit,
+             &AOB, &ZOB, &HOB, &outSphere->r, &outSphere->d);
+
+    return (outSphere);
+}
+
+psPlane* psCoordCellToFPA(psPlane* fpaCoord,
+                          const psPlane* cellCoord,
+                          const psCell* cell)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(cellCoord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(cell);
+
+    return (psPlaneTransformApply(fpaCoord, cell->toFPA, cellCoord));
+}
+
+psSphere* psCoordCellToSky(psSphere* skyCoord,
+                           const psPlane* cellCoord,
+                           double color,
+                           double magnitude,
+                           const psCell* cell)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(cellCoord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(cell);
+
+    psPlane* fpaCoord = NULL;
+    psPlane* tpCoord = NULL;
+    psFPA* parFPA = (cell->parent)->parent;
+    psGrommit* tmpGrommit = NULL;
+
+    // Convert the input cell coordinates to FPA coordinates.
+    fpaCoord = psPlaneTransformApply(fpaCoord, cell->toFPA, cellCoord);
+
+    // Convert the FPA coordinates to tangent plane Coordinates.
+    tpCoord = psPlaneDistortApply(tpCoord, parFPA->toTangentPlane,
+                                  fpaCoord, color, magnitude);
+
+    // Generate a grommit for this FPA.
+    tmpGrommit = psGrommitAlloc(parFPA->exposure);
+
+    // Convert the tangent plane Coordinates to sky coordinates.
+    skyCoord = psCoordTPToSky(skyCoord, tpCoord, tmpGrommit);
+
+    psFree(fpaCoord);
+    psFree(tpCoord);
+    psFree(tmpGrommit);
+
+    return(skyCoord);
+}
+
+psSphere* psCoordCellToSkyQuick(psSphere* outSphere,
+                                const psPlane* cellCoord,
+                                const psCell* cell)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(cellCoord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(cell);
+
+    psPlane *tpCoord = NULL;
+    psChip *chip = cell->parent;
+    psFPA *FPA = chip->parent;
+    psProjectionType oldProjectionType;
+
+    if (outSphere == NULL) {
+        outSphere = (psSphere* ) psAlloc(sizeof(psSphere));
+    }
+
+    // Determine the tangent plane coordinates.
+    tpCoord = psPlaneTransformApply(tpCoord, cell->toTP, cellCoord);
+
+    // Save the old projection type and set the new projection type to TAN.
+    oldProjectionType = FPA->projection->type;
+    FPA->projection->type = PS_PROJ_TAN;
+
+    // Deproject the tangent plane coordinates a sphere.
+    outSphere = psDeproject(tpCoord, FPA->projection);
+
+    // Restore old projection type.  Free memory.
+    FPA->projection->type = oldProjectionType;
+    psFree(tpCoord);
+
+    return (outSphere);
+}
+
+/*****************************************************************************
+XXX: What about units for the (x,y) coords?
+ *****************************************************************************/
+psPlane* psCoordSkyToTP(psPlane* tpCoord,
+                        const psSphere* in,
+                        const psGrommit* grommit)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(in);
+    PS_CHECK_NULL_PTR_RETURN_NULL(grommit);
+
+    char* type = "RA";
+
+    if (tpCoord == NULL) {
+        tpCoord = (psPlane* ) psAlloc(sizeof(psPlane));
+    }
+
+    slaOapqk(type, in->r, in->d, (double*)grommit, &tpCoord->x, &tpCoord->y);
+
+    return(tpCoord);
+}
+
+
+psPlane* psCoordTPToFPA(psPlane* fpaCoord,
+                        const psPlane* tpCoord,
+                        double color,
+                        double magnitude,
+                        const psFPA* fpa)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(tpCoord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(fpa);
+
+    return (psPlaneDistortApply(fpaCoord, fpa->fromTangentPlane,
+                                tpCoord, color, magnitude));
+}
+
+psPlane* psCoordFPAToChip(psPlane* chipCoord,
+                          const psPlane* fpaCoord,
+                          const psChip* chip)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(fpaCoord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(chip);
+    PS_CHECK_NULL_PTR_RETURN_NULL(chip->parent);
+
+    chipCoord = psPlaneTransformApply(chipCoord, chip->fromFPA, fpaCoord);
+    return(chipCoord);
+}
+
+psPlane* psCoordChipToCell(psPlane* cellCoord,
+                           const psPlane* chipCoord,
+                           const psCell* cell)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(chipCoord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(cell);
+    PS_CHECK_NULL_PTR_RETURN_NULL(cell->parent);
+
+    cellCoord = psPlaneTransformApply(cellCoord, cell->fromChip, chipCoord);
+    return(cellCoord);
+}
+
+psPlane* psCoordSkyToCell(psPlane* cellCoord,
+                          const psSphere* skyCoord,
+                          double color,
+                          double magnitude,
+                          const psCell* cell)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(skyCoord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(cell);
+
+    psChip *parChip = cell->parent;
+    psFPA *parFPA = parChip->parent;
+    psGrommit* grommit = parFPA->grommit;
+
+    // Convert the skyCoords to tangent plane coords.
+    psPlane *tpCoord = psCoordSkyToTP(tpCoord, skyCoord, grommit);
+
+    // Convert the tangent plane coords to FPA coords.
+    psPlane *fpaCoord = psCoordTPToFPA(fpaCoord, tpCoord, color,
+                                       magnitude, parFPA);
+
+    // Convert the FPA coords to chip coords.
+    psPlane *chipCoord = psCoordFPAToChip(chipCoord, fpaCoord, parChip);
+
+    // Convert the chip coords to cell coords.
+    cellCoord = psCoordChipToCell(cellCoord, chipCoord, cell);
+
+    psFree(tpCoord);
+    psFree(fpaCoord);
+    psFree(chipCoord);
+
+    return (cellCoord);
+}
+
+psPlane* psCoordSkyToCellQuick(psPlane* cellCoord,
+                               const psSphere* skyCoord,
+                               const psCell* cell)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(skyCoord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(cell);
+
+    psPlane *tpCoord = NULL;
+    psChip *whichChip = cell->parent;
+    psFPA *whichFPA = whichChip->parent;
+    psProjectionType oldProjectionType;
+    psPlaneTransform *TPtoCell = NULL;
+
+    // Save the old projection type and set the new projection type to TAN.
+    oldProjectionType = whichFPA->projection->type;
+    whichFPA->projection->type = PS_PROJ_TAN;
+
+    if (cellCoord == NULL) {
+        cellCoord = (psPlane* ) psAlloc(sizeof(psPlane));
+    }
+
+    tpCoord = psProject(skyCoord, whichFPA->projection);
+
+    // generate an error if cell->toTP is not linear.
+    if (0 == isProjectionLinear(cell->toTP)) {
+        psAbort(__func__, "the cell->toTP transfrom is not linear.\n");
+    }
+
+    TPtoCell = invertPlaneTransform(cell->toTP);
+    cellCoord = psPlaneTransformApply(cellCoord, TPtoCell, tpCoord);
+
+    // Restore old projection type.  Free memory.
+    whichFPA->projection->type = oldProjectionType;
+    psFree(tpCoord);
+    return (cellCoord);
+}
+
Index: /branches/rel3/psLib/src/astronomy/psAstrometry.h
===================================================================
--- /branches/rel3/psLib/src/astronomy/psAstrometry.h	(revision 2163)
+++ /branches/rel3/psLib/src/astronomy/psAstrometry.h	(revision 2163)
@@ -0,0 +1,527 @@
+/** @file  psAstrometry.h
+*
+*  @brief This file defines the basic types for astronomical coordinate
+*  transformation
+*
+*  @ingroup AstroImage
+*
+*  @author George Gusciora, MHPCC
+*
+*  @version $Revision: 1.29 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-12 20:53:02 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#ifndef PS_ASTROMETRY_H
+#define PS_ASTROMETRY_H
+
+#include "psType.h"
+#include "psImage.h"
+#include "psArray.h"
+#include "psList.h"
+#include "psFunctions.h"
+#include "psMetadata.h"
+#include "psCoord.h"
+#include "psPhotometry.h"
+
+struct psCell;
+struct psChip;
+struct psFPA;
+struct psExposure;
+
+/// @addtogroup AstroImage
+/// @{
+
+/** Wallace's Grommit
+ *
+ *  SLALib requires several elements to perform the transformations between
+ *  the tangent plane and the sky.  Pre-computing these quantities for each
+ *  exposure means that subsequent transformations are faster.  For historical
+ *  reasons, this structure is known colloquially as "Wallace's Grommit".
+ *
+ */
+typedef struct
+{
+    const double latitude;             ///< geodetic latitude (radians)
+    const double sinLat;               ///< sine of geodetic latitude
+    const double cosLat;               ///< cosine of geodetic latitude
+    const double abberationMag;        ///< magnitude of diurnal aberration vector
+    const double height;               ///< height (HM)
+    const double temperature;          ///< ambient temperature (TDK)
+    const double pressure;             ///< pressure (PMB)
+    const double humidity;             ///< relative humidity (RH)
+    const double wavelength;           ///< wavelength (WL)
+    const double lapseRate;            ///< lapse rate (TLR)
+    const double refractA;             ///< refraction constant A (radians)
+    const double refractB;             ///< refraction constant B (radians)
+    const double longitudeOffset;      ///< longitude + ... (radians)
+    const double siderealTime;         ///< local apparent sidereal time (radians)
+}
+psGrommit;
+
+/** Fixed Pattern Corrections
+ *
+ *  The fixed pattern is a correction to the general astrometric solution
+ *  formed by summing the residuals from many observations. The intent is to
+ *  correct for higher-order distortions in the camera system on a coarse
+ *  grid (larger than individual pixels, but smaller than a single cell).
+ *  Hence, in addition to the offsets, we need to specify the size and scale
+ *  of the grid in x and y as well as the origin of the grid.
+ */
+typedef struct
+{
+    int nX;                            ///< Number of elements in x direction
+    int nY;                            ///< Number of elements in y direction
+    double x0;                         ///< X Position of 0,0 corner on focal plane
+    double y0;                         ///< Y Position of 0,0 corner on focal plane
+    double xScale;                     ///< Scale of the grid in x direction
+    double yScale;                     ///< Scale of the grid in x direction
+    /// XXX: I added the following memvers to facilitate the psFreeing of the x,y data structures.
+    int p_ps_xRows;                    ///< Number of rows in the x member
+    int p_ps_xCols;                    ///< Number of cols in the x member
+    int p_ps_yRows;                    ///< Number of rows in the y member
+    int p_ps_yCols;                    ///< Number of cols in the y member
+    double **x;                        ///< The grid of offsets in x
+    double **y;                        ///< The grid of offsets in y
+}
+psFixedPattern;
+
+/** Readout data structure.
+ *
+ *  A readout is the result of a single read of a cell (or a portion thereof).
+ *  It contains a pointer to the pixel data, and additional pointers to the
+ *  objects found in the readout, and the readout metadata.  It also contains
+ *  the offset from the lower-left corner of the chip, in the case that the
+ *  CCD was windowed.
+ *
+ */
+typedef struct
+{
+    const unsigned int colBins;        ///< Amount of binning in x-dimension
+    const unsigned int rowBins;        ///< Amount of binning in y-dimension
+    const int col0;                    ///< Offset from the left of chip.
+    const int row0;                    ///< Offset from the bottom of chip.
+
+    psImage* image;                    ///< Imaging area of readout
+    psImage* mask;                     ///< Mask area for readout
+    psList* objects;                   ///< Objects derived from Readout
+    psMetadata* metadata;              ///< Readout-level metadata
+}
+psReadout;
+
+/** Cell data structure
+ *
+ *  A cell consists of one or more readouts.  It also contains a pointer to the
+ *  cell's metadata, and its parent chip.  On the astrometry side, it also
+ *  contains coordinate transforms from the cell to chip, from the cell to
+ *  focal-plane, as well as a "quick and dirty" tranform from the cell to
+ *  sky coordinates.
+ *
+ */
+typedef struct
+{
+    psArray* readouts;                 ///< readouts from the cell
+    psMetadata* metadata;              ///< cell-level metadata
+
+    psPlaneTransform* toChip;          ///< transformations from cell to chip coordinates
+    psPlaneTransform* fromChip;        ///< transformations from chip to cell coordinates
+    psPlaneTransform* toFPA;           ///< transformations from cell to FPA coordinates
+    psPlaneTransform* toTP;            ///< transformations from cell to tangent plane coordinates
+
+    struct psChip* parent;             ///< chip in which contains this cell
+}
+psCell;
+
+/** Chip data structure
+ *
+ *  A chip consists of one or more cells (according to the number of amplifiers
+ *  on the CCD). It contains a pointer to the chip's metadata, and a pointer
+ *  to the parent focal plane.  For astrometry, it contains a coordinate
+ *  transform from the chip to the focal plane, and vis-versa.
+ *
+ */
+typedef struct psChip
+{
+    psArray* cells;                    ///< cells in the chip
+    psMetadata* metadata;              ///< chip-level metadata
+
+    psPlaneTransform* toFPA;           ///< transformation from chip to FPA coordinates
+    psPlaneTransform* fromFPA;         ///< transformation from FPA to chip coordinates
+
+    struct psFPA* parent;              ///< FPA which contains this chip
+}
+psChip;
+
+/** A Focal-Plane
+ *
+ *  A focal plane consists of one or more chips (according to the number of
+ *  contiguous silicon).  It contains pointers to the focal-plane's metadata
+ *  and the exposure information.  For astrometry, it contains a transformation
+ *  from the focal plane to the tangent plane and the fixed pattern residuals.
+ *  Since colors are involved in the transformation, it is necessary to specify
+ *  the color the transformation is defined.  We also include some values to
+ *  characterize the quality of the transformation: the root square deviation
+ *  for the x and y transformation fits, and the chi-squared for the
+ *  transformation fit.
+ *
+ */
+typedef struct psFPA
+{
+    psArray* chips;                    ///< chips in the focal plane array
+    psMetadata* metadata;              ///< focal-plane's metadata
+
+    psPlaneDistort* fromTangentPlane;  ///< transformation from tangent plane to focal plane
+    psPlaneDistort* toTangentPlane;    ///< transformation from focal plane to tangent plane
+    psFixedPattern* pattern;           ///< fixed pattern residual offsets
+
+    const struct psExposure* exposure; ///< information about this exposure
+    psGrommit *grommit;                ///< Wallace's grommit
+
+    psPhotSystem* colorPlus;           ///< Color reference
+    psPhotSystem* colorMinus;          ///< Color reference
+    psProjection *projection;          ///< projection
+
+    float rmsX;                        ///< RMS for x transformation fits
+    float rmsY;                        ///< RMS for y transformation fits
+    float chi2;                        ///< chi^2 of astrometric solution
+}
+psFPA;
+
+/** Observatory Information
+ *
+ *  A container for the observatory data that doesn't change per exposure.
+ *
+ */
+typedef struct
+{
+    const char* name;                  ///< Name of observatory
+    const double latitude;             ///< Latitude of observatory, east positive (degrees?)
+    const double longitude;            ///< Longitude of observatory (degrees?)
+    const double height;               ///< Height of observatory in meters
+    const double tlr;                  ///< Tropospheric Lapse Rate
+}
+psObservatory;
+
+/** Exposure Information
+ *
+ *  Several quantities from the telescope in order to make a first guess at
+ *  the astrometric solution.  From these quantities, further quantities can
+ *  be derivedand stored for later use.
+ *
+ */
+typedef struct psExposure
+{
+    const double ra;                   ///< Telescope boresight, right ascention
+    const double dec;                  ///< Telescope boresight, declination
+    const double hourAngle;            ///< Hour angle
+    const double zenithDistance;       ///< Zenith distance
+    const double azimuth;              ///< Azimuth
+    const psTime* time;                ///< Time of observation
+    const float rotAngle;              ///< Rotator position angle in degrees? XXX: see bug#209
+    const float temperature;           ///< Air temperature in Kelvin
+    const float pressure;              ///< Air pressure in mB
+    const float humidity;              ///< Relative humidity, for refraction
+    const float exposureTime;          ///< Exposure time
+    const float wavelength;            ///< Wavelength in microns
+    const psObservatory* observatory;  ///< Observatory data
+
+    /* Derived quantities */
+    const double lst;                  ///< Local Sidereal Time
+    const float positionAngle;         ///< Position angle
+    const float parallacticAngle;      ///< Parallactic angle
+    const float airmass;               ///< Airmass, calculated from zenith distance
+    const float parallacticFactor;     ///< Parallactic factor
+    const char* cameraName;            ///< name of camera which provided exposure
+    const char* telescopeName;         ///< name of telescope which provided exposure
+}
+psExposure;
+
+/** Allocator for psFixedPattern struct
+ *
+ *  Allocates a new psFixedPattern struct with the attributes coorsponding
+ *  to the parameters set to the said input values.
+ *
+ *  @return psFixedPattern*     New psFixedPattern struct.
+ */
+psFixedPattern* psFixedPatternAlloc(
+    double x0,           ///< X Position of 0,0 corner on focal plane
+    double y0,           ///< Y Position of 0,0 corner on focal plane
+    double xScale,       ///< Scale of the grid in x direction
+    double yScale,       ///< Scale of the grid in x direction
+    const psImage *x,    ///< The grid of offsets in x
+    const psImage *y     ///< The grid of offsets in y
+);
+
+
+/** Allocator for psExposure
+ *
+ *  We need several quantities from the telescope in order to make a first
+ *  guess at the astrometric solution. From these quantities, further
+ *  quantities can be derived and stored for later use.
+ *
+ *  @return     psExposure*    New psExposure struct
+ */
+psExposure* psExposureAlloc(
+    double ra,                         ///< Telescope boresight, right ascention
+    double dec,                        ///< Telescope boresight, declination
+    double hourAngle,                  ///< Hour angle
+    double zenithDistance,             ///< Zenith distance
+    double azimuth,                    ///< Azimuth
+    const psTime* time,                ///< time of observation
+    float rotAngle,                    ///< Rotator position angle
+    float temperature,                 ///< Temperature
+    float pressure,                    ///< Pressure
+    float humidity,                    ///< Relative humidity
+    float exposureTime,                ///< Exposure time
+    float wavelength,                  ///< wavelength
+    const psObservatory* observatory   ///< Observatory data
+);
+
+/** Allocator for psObservatory
+ *
+ *  This function shall construct a new psObservatory with attributes 
+ *  cooresponding to the function parameters.
+ *
+ *  @return psObservatory*    new psObservatory struct
+ */
+psObservatory* psObservatoryAlloc(
+    const char* name,                  ///< Name of observatory
+    double latitude,                   ///< Latitude of observatory, east positive
+    double longitude,                  ///< Longitude of observatory
+    double height,                     ///< Height of observatory
+    double tlr                         ///< Tropospheric Lapse Rate
+);
+
+/** Allocator for psFPA
+ *
+ *  This function shall make an empty psFPA, with the nChips allocated
+ *  pointers to psChips being set to NULL; all other pointers in the structure
+ *  shall be initialized to NULL, apart from the grommit, which shall be
+ *  constructed on the basis of the exp parameter.
+ *
+ *  @return psFPA*    a newly allocated psFPA
+ */
+psFPA* psFPAAlloc(
+    int nChips,                        ///< number of chips in the FPA
+    const psExposure* exp              ///< the exposure information
+);
+
+/** Allocates a psChip
+ *
+ *  This allocator shall make an empty psChip, with the nCells allocated
+ *  pointers to psCells being set to NULL; all other pointers in the structure
+ *  shall be initialized to NULL.
+ *
+ *  @return psChip*    newly allocated psChip
+ */
+psChip* psChipAlloc(
+    int nCells,                        ///< number of cells in Chip
+    psFPA* parentFPA                   ///< parent FPA
+);
+
+/** Allocates a psCell
+ *
+ *  The constructor shall make an empty psCell, with the nReadouts allocated
+ *  pointers to psReadouts being set to NULL; all other pointers in the
+ *  structure shall be initialized to NULL.
+ *
+ *  @return psCell*    newly allocated psCell
+ */
+psCell* psCellAlloc(
+    int nReadouts,                     ///< number of readouts in cell
+    psChip* parentChip                 ///< parent Chip
+);
+
+/** Allocates a psReadout
+ *
+ *  All pointers in the structure other than the image shall be initialized
+ *  to NULL.
+ *
+ *  @return psReadout*    newly allocated psReadout
+ */
+psReadout* psReadoutAlloc(
+    int col0,                          ///< offset from the left of the cell
+    int row0,                          ///< offset from the bottom of the cell
+    const psImage* image               ///< image of the readout
+);
+
+/** Allocates a Wallace's Grommit structure.
+ *
+ *  The psGrommit is calculated from telescope information for the particular
+ *  exposure.
+ *
+ *  @return psGrommit* New grommit structure.
+ */
+psGrommit* psGrommitAlloc(
+    const psExposure* exp              ///< the cooresponding exposure structure.
+);
+
+/** Find cooresponding cell for given FPA coordinate
+ *
+ *  @return psCell*    the cell cooresponding to the coord in FPA
+ */
+psCell* psCellInFPA(
+    const psPlane* coord,              ///< the coordinate in FPA plane
+    const psFPA* FPA                   ///< the FPA to search for the cell
+);
+
+/** Find cooresponding chip for given FPA coordinate
+ *
+ *  @return psChip*    the chip cooresponding to coord
+ */
+psChip* psChipInFPA(
+    const psPlane* coord,              ///< the coordinate in FPA plane
+    const psFPA* FPA                   ///< the FPA to search for the cell
+);
+
+/** Find cooresponding cell for given Chip coordinate
+ *
+ *  @return psCell*    the cell cooresponding to coord
+ */
+psCell* psCellInChip(
+    const psPlane* coord,              ///< the coordinate in Chip plane
+    const psChip* chip                 ///< the chip to search for the cell
+);
+
+/** Translate a cell coordinate into a chip coordinate
+ *
+ *  @return psPlane*    the resulting chip coordinate
+ */
+psPlane* psCoordCellToChip(
+    psPlane* out,                      ///< a plane struct to recycle. If NULL, a new struct is created
+    const psPlane* in,                 ///< the coordinate within Cell
+    const psCell* cell                 ///< the Cell in interest
+);
+
+/** Translate a chip coordinate into a FPA coordinate
+ *
+ *  @return psPlane*    the resulting FPA coordinate
+ */
+psPlane* psCoordChipToFPA(
+    psPlane* out,                      ///< a plane struct to recycle. If NULL, a new struct is created
+    const psPlane* in,                 ///< the coordinate within Chip
+    const psChip* chip                 ///< the chip in interest
+);
+
+/** Translate a FPA coordinate into a Tangent Plane coordinate
+ *
+ *  @return psPlane*    the resulting Tangent Plane coordinate
+ */
+psPlane* psCoordFPAToTP(
+    psPlane* out,                      ///< a plane struct to recycle. If NULL, a new struct is created
+    const psPlane* in,                 ///< the coordinate within FPA
+    double color,                      ///< Color of source
+    double magnitude,                  ///< Magnitude of source
+    const psFPA* fpa                   ///< the FPA in interest
+);
+
+/** Translate a Tangent Plane coordinate into a Sky coordinate
+ *
+ *  @return psSphere*    the resulting Sky coordinate
+ */
+psSphere* psCoordTPToSky(
+    psSphere* out,                     ///< a sphere struct to recycle. If NULL, a new struct is created
+    const psPlane* in,                 ///< the coordinate within Tangent Plane
+    const psGrommit* grommit           ///< the grommit of the tangent plane
+);
+
+/** Translate a cell coordinate into a FPA coordinate
+ *
+ *  @return psPlane*    the resulting FPA coordinate
+ */
+psPlane* psCoordCellToFPA(
+    psPlane* out,                      ///< a plane struct to recycle. If NULL, a new struct is created
+    const psPlane* in,                 ///< the coordinate within cell
+    const psCell* cell                 ///< the cell in interest
+);
+
+/** Translate a cell coordinate into a Sky coordinate
+ *
+ *  @return psSphere*    the resulting Sky coordinate
+ */
+psSphere* psCoordCellToSky(
+    psSphere* out,                     ///< a sphere struct to recycle. If NULL, a new struct is created
+    const psPlane* in,                 ///< the coordinate within cell
+    double color,                      ///< Color of source
+    double magnitude,                  ///< Magnitude of source
+    const psCell* cell                 ///< the cell in interest
+);
+
+/** Translate a cell coordinate into a Sky coordinate using a 'quick and
+ *  dirty' method
+ *
+ *  @return psSphere*    the resulting Sky coordinate
+ */
+psSphere* psCoordCellToSkyQuick(
+    psSphere* out,                     ///< a sphere struct to recycle. If NULL, a new struct is created
+    const psPlane* in,                 ///< the coordinate within cell
+    const psCell* cell                 ///< the cell in interest
+);
+
+/** Translate a Sky coordinate into a Tangent Plane coordinate
+ *
+ *  @return psPlane*    the resulting Tangent Plane coordinate
+ */
+psPlane* psCoordSkyToTP(
+    psPlane* out,                      ///< a plane struct to recycle. If NULL, a new struct is created
+    const psSphere* in,                ///< the sky coordinate
+    const psGrommit* grommit           ///< the grommit
+);
+
+/** Translate a Tangent Plane coordinate into a FPA coordinate
+ *
+ *  @return psPlane*    the resulting FPA coordinate
+ */
+psPlane* psCoordTPToFPA(
+    psPlane* out,                      ///< a plane struct to recycle. If NULL, a new struct is created
+    const psPlane* in,                 ///< the coordinate within tangent plane
+    double color,                      ///< Color of source
+    double magnitude,                  ///< Magnitude of source
+    const psFPA* fpa                   ///< the FPA of interest
+);
+
+/** Translate a FPA coordinate into a chip coordinate
+ *
+ *  @return psPlane*    the resulting chip coordinate
+ */
+psPlane* psCoordFPAToChip(
+    psPlane* out,                      ///< a plane struct to recycle. If NULL, a new struct is created
+    const psPlane* in,                 ///< the FPA coordinate
+    const psChip* chip                 ///< the chip of interest
+);
+
+/** Translate a chip coordinate into a cell coordinate
+ *
+ *  @return psPlane*    the resulting cell coordinate
+ */
+psPlane* psCoordChipToCell(
+    psPlane* out,                      ///< a plane struct to recycle. If NULL, a new struct is created
+    const psPlane* in,                 ///< the Chip coordinate
+    const psCell* cell                 ///< the cell of interest
+);
+
+/** Translate a sky coordinate into a cell coordinate
+ *
+ *  @return psPlane*    the resulting cell coordinate
+ */
+psPlane* psCoordSkyToCell(
+    psPlane* out,                      ///< a plane struct to recycle. If NULL, a new struct is created
+    const psSphere* in,                ///< the Sky coordinate
+    double color,                      ///< Color of source
+    double magnitude,                  ///< Magnitude of source
+    const psCell* cell                 ///< the cell of interest
+);
+
+/** Translate a sky coordinate into a cell coordinate using a 'quick and
+ *  dirty' method
+ *
+ *  @return psPlane*    the resulting cell coordinate
+ */
+psPlane* psCoordSkyToCellQuick(
+    psPlane* out,                      ///< a plane struct to recycle. If NULL, a new struct is created
+    const psSphere* in,                ///< the Sky coordinate
+    const psCell* cell                 ///< the cell of interest
+);
+
+#endif
Index: /branches/rel3/psLib/src/astronomy/psAstronomyErrors.dat
===================================================================
--- /branches/rel3/psLib/src/astronomy/psAstronomyErrors.dat	(revision 2163)
+++ /branches/rel3/psLib/src/astronomy/psAstronomyErrors.dat	(revision 2163)
@@ -0,0 +1,8 @@
+#
+#  This file is used to generate psAstronomyErrors.h content
+#
+#  Format is:
+#  ERRORNAME(one word)    ERROR_TEXT
+#
+#  N.B. in code, the ERRORNAME appears as PS_ERRORTEXT_ERRORNAME
+####################################################################
Index: /branches/rel3/psLib/src/astronomy/psAstronomyErrors.h
===================================================================
--- /branches/rel3/psLib/src/astronomy/psAstronomyErrors.h	(revision 2163)
+++ /branches/rel3/psLib/src/astronomy/psAstronomyErrors.h	(revision 2163)
@@ -0,0 +1,35 @@
+/** @file  psAstronomyErrors.h
+ *
+ *  @brief Contains the error text for the astronomy functions
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-11 00:43:54 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_SYSUTILS_ERRORS_H
+#define PS_SYSUTILS_ERRORS_H
+
+/* N.B., lines between '//~Start' and '//~End' are automatic generated from
+ * the template following the '//~Start'.  The template is used to generate
+ * the other lines by, for each error text in psAstronomyErrors.dat, the following
+ * substitutions are made:
+ *     $1  The error text macro name (first word in the psAstronomyErrors.dat lines)
+ *     $2  The error text (rest of the line in psAstronomyErrors.dat)
+ *     $n  The order of the source line in psAstronomyErrors.dat (comments excluded)
+ * 
+ * DO NOT EDIT THE LINES BETWEEN //~Start and //~End!  ANY CHANGES WILL BE OVERWRITTEN.
+ */
+
+#define PS_ERRORNAME_DOMAIN "psLib.astronomy."
+
+//~Start #define PS_ERRORTEXT_$1 "$2"
+#define PS_ERRORTEXT_ ""
+//~End
+
+#endif
Index: /branches/rel3/psLib/src/astronomy/psCoord.c
===================================================================
--- /branches/rel3/psLib/src/astronomy/psCoord.c	(revision 2163)
+++ /branches/rel3/psLib/src/astronomy/psCoord.c	(revision 2163)
@@ -0,0 +1,470 @@
+/** @file  psCoord.c
+*
+*  @brief Contains basic coordinate transformation definitions and operations
+*
+*  This file defines the basic types for astronomical coordinate
+*  transformation
+*
+*  @ingroup CoordinateTransform
+*
+*  @author George Gusciora, MHPCC
+*
+*  @version $Revision: 1.25 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-14 01:17:50 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include "psType.h"
+#include "psImage.h"
+#include "psArray.h"
+#include "psList.h"
+#include "psCoord.h"
+#include "psMemory.h"
+#include "psAbort.h"
+#include "psTime.h"
+#include "psConstants.h"
+#include "psError.h"
+#include <math.h>
+#include <float.h>
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+#define PS_COT(X) (1.0 / atan(X))
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+static float p_psArg(float x, float y);
+
+/******************************************************************************
+XXX: Verify this arc tan function.
+XXX: macro
+XXX: I don't think this arg() is correct.
+ *****************************************************************************/
+
+float p_psArg(float x,
+              float y)
+{
+    if (y!= 0.0) {
+        return(atan(y/x));
+    } else {
+        return(0.5 * M_PI);
+    }
+    return (0.0);
+    /*
+        if (x > 0) {
+            return (atan(y / x));
+        } else if ((x == 0) && (y == 0)) {
+            return (0.5 * M_PI);
+        } else if ((x == 0) && (y == 0)) {
+            return (-0.5 * M_PI);
+        } else if ((x == 0) && (y == 0)) {
+            return (M_PI + atan(y / x));
+        } else if ((x == 0) && (y == 0)) {
+            return (-M_PI + atan(y / x));
+        }
+        psAbort(__func__, "Unacceptable range for (p_psArg(%f, %f).\n", x, y);
+    */
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+psPlane* psPlaneTransformApply(psPlane* out,
+                               const psPlaneTransform* transform,
+                               const psPlane* coords)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(transform);
+    PS_CHECK_NULL_PTR_RETURN_NULL(coords);
+    if (out == NULL) {
+        out = (psPlane* ) psAlloc(sizeof(psPlane));
+    }
+    out->x = psDPolynomial2DEval(coords->x, coords->y, transform->x);
+    out->y = psDPolynomial2DEval(coords->x, coords->y, transform->y);
+    return (out);
+}
+
+/******************************************************************************
+This transformation takes into account parameters beyond an objects spatial
+coordinates: term3 and term4 (magnitude and color).
+ *****************************************************************************/
+psPlane* psPlaneDistortApply(psPlane* out,
+                             const psPlaneDistort* transform,
+                             const psPlane* coords,
+                             float color,
+                             float magnitude)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(transform);
+    PS_CHECK_NULL_PTR_RETURN_NULL(coords);
+    if (out == NULL) {
+        out = (psPlane* ) psAlloc(sizeof(psPlane));
+    }
+    out->x = psDPolynomial4DEval(coords->x, coords->y, color, magnitude, transform->x);
+    out->y = psDPolynomial4DEval(coords->x, coords->y, color, magnitude, transform->y);
+    return (out);
+}
+
+/******************************************************************************
+This function prototype has been modified since the SDRS.
+ *****************************************************************************/
+psSphereTransform* psSphereTransformAlloc(double NPlat,
+        double Xo,
+        double xo)
+{
+    psSphereTransform* tmp = (psSphereTransform* ) psAlloc(sizeof(psSphereTransform));
+
+    tmp->sinPhi = sin(NPlat);
+    tmp->cosPhi = cos(NPlat);
+    tmp->Xo = Xo;
+    tmp->xo = xo;
+
+    return (tmp);
+}
+
+/******************************************************************************
+This algorithm comes from an email from Gene.  I assume (x,y) corresponds to
+(r,d) in the sphere coordinates.
+ 
+XXX: In Gene's email, there are different variables with similar names (y
+and Y) and in the code, there's cos_y, cos_Y, and cos(y).  Verify that there
+are no typo's.
+ *****************************************************************************/
+psSphere* psSphereTransformApply(psSphere* out,
+                                 const psSphereTransform* transform,
+                                 const psSphere* coord)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(transform);
+    PS_CHECK_NULL_PTR_RETURN_NULL(coord);
+    double sinY = 0.0;
+    double cosY = 0.0;
+    double sinX = 0.0;
+    double cosX = 0.0;
+    double x = 0.0;
+    double y = 0.0;
+    double dx = 0.0;
+
+    if (out == NULL) {
+        out = (psSphere* ) psAlloc(sizeof(psSphere));
+    }
+
+    x = coord->r;
+    y = coord->d;
+    dx = x - transform->xo;
+    sinY = cos(y) * sin(dx) * transform->sinPhi + sin(y) * transform->cosPhi;
+    cosY = sqrt(1.0 - sinY * sinY);
+    sinX = (cos(y) * sin(dx) * transform->cosPhi - sin(y) * transform->sinPhi) / cos(y);
+    cosX = cos(y) * cos(dx) / cos(y);
+
+    out->r = atan2(sinX, cosX) + transform->Xo;
+    out->d = atan2(sinY, cosY);
+
+    return (out);
+}
+
+psSphereTransform* psSphereTransformICRStoEcliptic(psTime time)
+{
+    struct tm *tmTime = psTimeToTM(&time);
+    double year = (double)(1900 + tmTime->tm_year);
+    double T = year / 100.0;
+    double phi = -23.452294 + 0.013013 * T + 0.000001639 * T * T - 0.000000503 * T * T * T;
+    double Xo = 0.0;
+    double xo = 0.0;
+
+    psFree(tmTime);
+    return (psSphereTransformAlloc(phi, Xo, xo));
+}
+
+psSphereTransform* psSphereTransformEcliptictoICRS(psTime time)
+{
+    struct tm *tmTime = psTimeToTM(&time);
+    double year = (double)(1900 + tmTime->tm_year);
+    double T = year / 100.0;
+    double phi = +23.452294 - 0.013013 * T - 0.000001639 * T * T + 0.000000503 * T * T * T;
+    double Xo = 0.0;
+    double xo = 0.0;
+
+    psFree(tmTime);
+    return (psSphereTransformAlloc(phi, Xo, xo));
+}
+
+psSphereTransform* psSphereTransformICRStoGalatic(void)
+{
+    return (psSphereTransformAlloc(62.6, 282.25, 33.0));
+}
+
+psSphereTransform* psSphereTransformGalatictoICRS(void)
+{
+    return (psSphereTransformAlloc(-62.6, 33.0, 282.25));
+}
+
+/******************************************************************************
+XXX: Waiting for the definition of the PS_PROJ_PAR projection.
+XXX: Waiting for the definition of the PS_PROJ_GLS projection.
+XXX: get rid of the psAborts
+ *****************************************************************************/
+psPlane* psProject(const psSphere* coord,
+                   const psProjection* projection)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(coord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(projection);
+
+    float R = 0.0;
+    float alpha = 0.0;
+    psPlane* tmp = (psPlane* ) psAlloc(sizeof(psPlane));
+
+    if (projection->type == PS_PROJ_TAN) {
+        R = PS_COT(coord->r) * (180.0 / M_PI);
+        tmp->x = R * sin(coord->d);
+        tmp->y = R * cos(coord->d);
+
+    } else if (projection->type == PS_PROJ_SIN) {
+        R = cos(coord->r) * (180.0 / M_PI);
+        tmp->x = R * sin(coord->d);
+        tmp->y = R * cos(coord->d);
+
+    } else if (projection->type == PS_PROJ_CAR) {
+        tmp->x = coord->d;
+        tmp->y = coord->r;
+
+    } else if (projection->type == PS_PROJ_MER) {
+        tmp->x = coord->d;
+        tmp->y = log(tan(45.0 + (0.5 * coord->r))) * 180.0 / M_PI;
+
+    } else if (projection->type == PS_PROJ_AIT) {
+        alpha = 1.0 / ((180.0 / M_PI) * sqrt(1.0 + (cos(coord->r) *
+                                             cos(0.5 * coord->d) * 0.5)));
+
+        tmp->x = 2.0 * alpha * cos(coord->r) * sin(0.5 * coord->d);
+        tmp->y = alpha * sin(coord->d);
+
+    } else if (projection->type == PS_PROJ_PAR) {
+        psAbort(__func__, "The projection type PS_PROJ_PAR is undefined.\n");
+
+    } else if (projection->type == PS_PROJ_GLS) {
+        psAbort(__func__, "The projection type PS_PROJ_GLS is undefined.\n");
+    } else {
+        psAbort(__func__, "Unknown projection type.\n");
+    }
+
+    return (tmp);
+}
+
+/******************************************************************************
+XXX: Waiting for the definition of the PS_PROJ_PAR projection.
+XXX: Waiting for the definition of the PS_PROJ_GLS projection.
+XXX: get rid of the psAborts
+ *****************************************************************************/
+psSphere* psDeproject(const psPlane* coord,
+                      const psProjection* projection)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(coord);
+    PS_CHECK_NULL_PTR_RETURN_NULL(projection);
+
+    float R = 0.0;
+    float chu = 0.0;
+    float chu1 = 0.0;
+    float chu2 = 0.0;
+    psSphere* tmp = (psSphere* ) psAlloc(sizeof(psSphere));
+
+    if (projection->type == PS_PROJ_TAN) {
+        R = sqrt((coord->x * coord->x) + (coord->y * coord->y));
+        tmp->d = p_psArg(-coord->y, coord->x);
+        tmp->r = atan(180.0 / (R * M_PI));
+
+    } else if (projection->type == PS_PROJ_SIN) {
+        R = sqrt((coord->x * coord->x) + (coord->y * coord->y));
+        tmp->d = p_psArg(-coord->y, coord->x);
+        tmp->r = acos((R * M_PI) / 180.0);
+
+    } else if (projection->type == PS_PROJ_CAR) {
+        tmp->d = coord->x;
+        tmp->r = coord->y;
+
+    } else if (projection->type == PS_PROJ_MER) {
+        tmp->d = coord->x;
+        tmp->r = (2.0 * atan(exp((coord->y * M_PI / 180.0)))) - 180.0;
+
+    } else if (projection->type == PS_PROJ_AIT) {
+        chu1 = (coord->x * M_PI) / 720.0;
+        chu1 *= chu1;
+        chu2 = (coord->y * M_PI) / 360.0;
+        chu2 *= chu2;
+        chu = sqrt(1.0 - chu1 - chu2);
+        tmp->d = 2.0 * p_psArg((2.0 * chu * chu) - 1.0, (coord->x * chu * M_PI) / 360.0);
+        tmp->r = asin((coord->y * chu * M_PI) / 180.0);
+
+    } else if (projection->type == PS_PROJ_PAR) {
+        psAbort(__func__, "The projection type PS_PROJ_PAR is undefined.\n");
+
+    } else if (projection->type == PS_PROJ_GLS) {
+        psAbort(__func__, "The projection type PS_PROJ_GLG is undefined.\n");
+    } else {
+        psAbort(__func__, "Unknown projection type.\n");
+    }
+
+    return (tmp);
+}
+
+/******************************************************************************
+The basic idea is to project both positions onto the linear plane, with
+position1 at the center, then calculate the linear offset between those
+projections.
+ 
+XXX: Do I need to check for unacceptable transformation parameters?  Maybe,
+     if the points are on the North/South Pole, etc?
+ 
+XXX: Do I need to somehow scale this projection?
+ 
+XXX: Does PS_LINEAR mode make sense?  The result must be returned in psSphere
+     regardless of the mode.
+ 
+XXX: How to compound errors?
+ *****************************************************************************/
+psSphere* psSphereGetOffset(const psSphere* restrict position1,
+                            const psSphere* restrict position2,
+                            psSphereOffsetMode mode,
+                            psSphereOffsetUnit unit)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(position1);
+    PS_CHECK_NULL_PTR_RETURN_NULL(position2);
+
+    psPlane* lin;
+    psProjection proj;
+    psSphere* tmp;
+
+    if (mode == PS_LINEAR) {
+        proj.R = position1->r;
+        proj.D = position1->d;
+        proj.Xs = 1.0;
+        proj.Ys = 1.0;
+        proj.type = PS_PROJ_TAN;
+
+        lin = psProject(position2, &proj);
+        tmp = psDeproject(lin, &proj);
+        psFree(lin);
+
+        // XXX: Do we need to convert units in tmp?
+        return (tmp);
+    } else if (mode == PS_SPHERICAL) {
+        tmp = (psSphere* ) psAlloc(sizeof(psSphere));
+        tmp->r = position2->r - position1->r;
+        tmp->d = position2->d - position1->d;
+
+        // Wrap these to an acceptable range.  This assumes that all
+        // angles are in radians.
+        tmp->r = fmod(tmp->r, 2*M_PI);
+        tmp->d = fmod(tmp->d, 2*M_PI);
+        tmp->rErr = 0.0;
+        tmp->dErr = 0.0;
+
+        if (unit == PS_ARCSEC) {
+            tmp->r = (tmp->r * 180.0 * 60.0 * 60.0) / M_PI;
+            tmp->d = (tmp->d * 180.0 * 60.0 * 60.0) / M_PI;
+        } else if (unit == PS_ARCMIN) {
+            tmp->r = (tmp->r * 180.0 * 60.0) / M_PI;
+            tmp->d = (tmp->d * 180.0 * 60.0) / M_PI;
+        } else if (unit == PS_DEGREE) {
+            tmp->r = (tmp->r * 180.0) / M_PI;
+            tmp->d = (tmp->d * 180.0) / M_PI;
+        } else if (unit == PS_RADIAN) {}
+        else {
+            psAbort(__func__, "Unknown offset unit: 0x%x\n", unit);
+        }
+
+        return (tmp);
+    }
+    psAbort(__func__, "Unrecognized offset mode\n");
+    return (NULL);
+}
+
+/******************************************************************************
+XXX: Do we need to check for unacceptable transformation parameters?  Maybe,
+     if the points are on the North/South Pole, etc?
+ 
+XXX: Do we need to somehow scale this projection?
+ 
+XXX: I copied the algorithm from the ADD exactly.
+ 
+XXX: Should we compound errors?
+ *****************************************************************************/
+
+psSphere* psSphereSetOffset(const psSphere* restrict position,
+                            const psSphere* restrict offset,
+                            psSphereOffsetMode mode,
+                            psSphereOffsetUnit unit)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(position);
+    PS_CHECK_NULL_PTR_RETURN_NULL(offset);
+
+    psPlane lin;
+    psSphere* tmp;
+    psProjection proj;
+    double tmpR = 0.0;
+    double tmpD = 0.0;
+
+    if (mode == PS_LINEAR) {
+        proj.R = position->r;
+        proj.D = position->d;
+        proj.Xs = 1.0;
+        proj.Ys = 1.0;
+        proj.type = PS_PROJ_TAN;
+
+        lin.x = offset->r;
+        lin.y = offset->d;
+
+        tmp = psDeproject(&lin, &proj);
+        return (tmp);
+
+    } else if (mode == PS_SPHERICAL) {
+        if (unit == PS_ARCSEC) {
+            tmpR = (M_PI * offset->r) / (180.0 * 60.0 * 60.0);
+            tmpD = (M_PI * offset->d) / (180.0 * 60.0 * 60.0);
+        } else if (unit == PS_ARCMIN) {
+            tmpR = (M_PI * offset->r) / (180.0 * 60.0);
+            tmpD = (M_PI * offset->d) / (180.0 * 60.0);
+        } else if (unit == PS_DEGREE) {
+            tmpR = (M_PI * offset->r) / (180.0);
+            tmpD = (M_PI * offset->d) / (180.0);
+        } else if (unit == PS_RADIAN) {
+            tmpR = offset->r;
+            tmpD = offset->d;
+        } else {
+            psAbort(__func__, "Unknown offset unit: 0x%x\n", unit);
+        }
+
+        tmp = (psSphere* ) psAlloc(sizeof(psSphere));
+        tmp->r = position->r + tmpR;
+        tmp->r = fmod(tmp->r, 2.0*M_PI);
+        tmp->d = position->d + tmpD;
+        tmp->d = fmod(tmp->d, 2.0*M_PI);
+        tmp->rErr = 0.0;
+        tmp->dErr = 0.0;
+
+        return (tmp);
+    }
+    psAbort(__func__, "Unrecognized offset mode\n");
+    return (NULL);
+}
Index: /branches/rel3/psLib/src/astronomy/psCoord.h
===================================================================
--- /branches/rel3/psLib/src/astronomy/psCoord.h	(revision 2163)
+++ /branches/rel3/psLib/src/astronomy/psCoord.h	(revision 2163)
@@ -0,0 +1,298 @@
+
+/** @file  psCoord.h
+*
+*  @brief Contains basic coordinate transformation definitions and operations
+*
+*  This file defines the basic types for astronomical coordinate 
+*  transformation
+*
+*  @ingroup CoordinateTransform
+*
+*  @author George Gusciora, MHPCC
+*
+*  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-12 01:34:09 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#ifndef PS_COORD_H
+#define PS_COORD_H
+
+#include "psType.h"
+#include "psImage.h"
+#include "psArray.h"
+#include "psList.h"
+#include "psFunctions.h"
+#include "psTime.h"
+
+/// @addtogroup CoordinateTransform
+/// @{
+
+/** Euclidiean Coordinate System.
+ *
+ *  Both detector and sky positions will be used extensively in the IPP. One
+ *  coordinate system to be used is linear coordinates which conform to 
+ *  Euclidean geometry. 
+ *
+ */
+typedef struct
+{
+    double x;                   ///< x position
+    double y;                   ///< y position
+    double xErr;                ///< Error in x position
+    double yErr;                ///< Error in y position
+}
+psPlane;
+
+/** Angular Coordinate System
+ *
+ *  Both detector and sky positions will be used extensively in the IPP. One 
+ *  coordinate system to be used is angular coordinates for which additional 
+ *  care must often be taken in comparison to a euclidiean coordinate system.
+ *
+ */
+typedef struct psSphere
+{
+    double r;                   ///< RA
+    double d;                   ///< Dec
+    double rErr;                ///< Error in RA
+    double dErr;                ///< Error in Dec
+}
+psSphere;
+
+/** 2D Polynomial Transform
+ *
+ *  A transform between coordinate systems that consists simply of two 2D 
+ *  polynomials to transform both components - the output coordinates depend 
+ *  only on the input coordinates and no other quantities of objects at those
+ *  coordinates. 
+ *
+ */
+typedef struct
+{
+    psDPolynomial2D* x;         ///< 2D polynomial transform of X coordinates
+    psDPolynomial2D* y;         ///< 2D polynomial transform of Y coordinates
+}
+psPlaneTransform;
+
+/** 4D Polynomial Transform
+ *
+ *  A transform between coordinate systems that consists of two 4D polynomials
+ *  in which the output coordinates are also specified to be a function of the 
+ *  magnitude and color of the object with the given coordinates. This type of 
+ *  coordinate transformation is necessary to represent the (color-dependent) 
+ *  optical distortions caused by the atmosphere and camera optics, and the 
+ *  possibly effects of charge transfer inefficiency.
+ *
+ *  The lowest two terms are the x and y axis of the target system.  The higher
+ *  two terms may represent magnitude and color terms.
+ */
+typedef struct
+{
+    psDPolynomial4D* x;         ///< 4D polynomial transform of X coordinates
+    psDPolynomial4D* y;         ///< 4D polynomial transform of Y coordinates
+}
+psPlaneDistort;
+
+/** Spherical Transform Definition
+ *
+ *  We need to be able to convert between ICRS, Galactic and Ecliptic 
+ *  coordinates, and potentially between arbitrary spherical coordinate 
+ *  systems. All of these basic spherical transformations represent rotations 
+ *  of the spherical coordinate reference. We specify a general 
+ *  transformation function which takes a structure, psSphereTransform, 
+ *  defining the transformation between two spherical coordinate systems 
+ *
+ */
+typedef struct
+{
+    double sinPhi;              ///< sin of North Pole lattitude
+    double cosPhi;              ///< cos of North Pole lattitude
+    double Xo;                  ///< First PT of Ares lon
+    double xo;                  ///< First PT of Ares equiv lon
+}
+psSphereTransform;
+
+/** Projection type for projection/deprojection
+ * 
+ *  @see psProject, psDeproject
+ *
+ */
+typedef enum {
+    PS_PROJ_TAN,                ///< Tangent projection
+    PS_PROJ_SIN,                ///< Sine projection
+    PS_PROJ_AIT,                ///< Aitoff projection
+    PS_PROJ_PAR,                ///< Par projection
+    PS_PROJ_GLS,                ///< GLS projection
+    PS_PROJ_CAR,                ///< CAR projection
+    PS_PROJ_MER,                ///< MER projection
+    PS_PROJ_NTYPE               ///< Number of types; must be last.
+} psProjectionType;
+
+/** Parameter set for projection/deprojection
+ * 
+ *  @see psProject, psDeproject
+ *
+ */
+typedef struct
+{
+    double R;                   ///< Coordinates of projection center
+    double D;                   ///< Coordinates of projection center
+    double Xs;                  ///< plate-scale in X direction
+    double Ys;                  ///< plate-scale in Y direction
+    psProjectionType type;      ///< Projection type
+}
+psProjection;
+
+/** Mode for Offset calculation between two sky positions
+ *
+ *  @see  psSphereGetOffset, psSphereSetOffset
+ *
+ */
+typedef enum {
+    PS_SPHERICAL,               ///< offset corresponds to an angular offset
+    PS_LINEAR                   ///< offset corresponds to a linear offset
+} psSphereOffsetMode;
+
+/** The units of the offset
+ *
+ *  @see  psSphereGetOffset, psSphereSetOffset
+ *
+ */
+typedef enum {
+    PS_ARCSEC,                  ///< Arcseconds
+    PS_ARCMIN,                  ///< Arcminutes
+    PS_DEGREE,                  ///< Degrees
+    PS_RADIAN                   ///< Radians
+} psSphereOffsetUnit;
+
+/** Applies the psPlaneTransform transform to a specified coordinate
+ *
+ *  @return psPlane*     resulting coordinate based on transform
+ */
+psPlane* psPlaneTransformApply(
+    psPlane* out,                      ///< a psPlane to recycle.  If NULL, a new one is generated.
+    const psPlaneTransform* transform, ///< the transform to apply
+    const psPlane* coords              ///< the coordinate to apply the transform above.
+);
+
+/** Applies the psPlaneDistort transform to a specified coordinate
+ *
+ *  @return psPlane*     resulting coordinate based on transform
+ */
+psPlane* psPlaneDistortApply(
+    psPlane* out,                      ///< a psPlane to recycle.  If NULL, a new one is generated.
+    const psPlaneDistort* transform,   ///< the transform to apply
+    const psPlane* coords,             ///< the coordinate to apply the transform above.
+    float term3,                       ///< third term -- maybe magnitude
+    float term4                        ///< forth term -- maybe color
+);
+
+/** Allocator for psSphereTransform
+ *
+ *  @return psSphereTransform*         newly allocated struct
+ */
+psSphereTransform* psSphereTransformAlloc(
+    double NPlat,                      ///< north pole latitude
+    double Xo,                         ///< First PT of Ares lon
+    double xo                          ///< First PT of Ares equiv lon
+);
+
+/** Applies the psSphereTransform transform for a specified coordinate
+ *
+ *  @return psSphere*      resulting coordinate based on transform
+ */
+psSphere* psSphereTransformApply(
+    psSphere* out,                     ///< a psSphere to recycle.  If NULL, a new one is generated.
+    const psSphereTransform* transform,///< the transform to apply
+    const psSphere* coord              ///< the coordinate to apply the transform above.x
+);
+
+/** Creates the appropriate transform for converting from ICRS to Ecliptic
+ *  coordinate systems.
+ *
+ *  @return psSphereTransform*     transform for ICRS->Ecliptic coordinate systems
+ */
+psSphereTransform* psSphereTransformICRStoEcliptic(
+    psTime time                        ///< the time for which the resulting transform will be valid
+);
+
+/** Creates the appropriate transform for converting from Ecliptic to ICRS
+ *  coordinate systems.
+ *
+ *  @return psSphereTransform*     transform for Ecliptic->ICRS coordinate systems
+ */
+psSphereTransform* psSphereTransformEcliptictoICRS(
+    psTime time                        ///< the time for which the resulting transform will be valid
+);
+
+/** Creates the appropriate transform for converting from ICRS to Galatic
+ *  coordinate systems.
+ *
+ */
+psSphereTransform* psSphereTransformICRStoGalatic(void);
+
+/** Creates the appropriate transform for converting from Galatic to ICRS
+ *  coordinate systems.
+ *
+ */
+psSphereTransform* psSphereTransformGalatictoICRS(void);
+
+/** Projects a spherical coordinate to a linear coordinate system
+ *
+ *  @return psPlane*    projected coordinate
+ */
+psPlane* psProject(
+    const psSphere* coord,             ///< coordinate to project
+    const psProjection* projection     ///< parameters of the projection
+);
+
+/** Reverse projection of a linear coordinate to a spherical coordinate system
+ *
+ *  @return psPlane*    projected coordinate
+ */
+psSphere* psDeproject(
+    const psPlane* coord,              ///< coordinate to project
+    const psProjection* projection     ///< parameters of the projection
+);
+
+/** Determines the offset (RA,Dec) on the sky between two positions.
+ *
+ *  Both an offset mode and an offset unit may be defined. The mode may be 
+ *  either PS_SPHERICAL, in which case the specified offset corresponds to an 
+ *  offset in angles, or it may be PS_LINEAR, in which case the offset 
+ *  corresponds to a linear offset in a local projection. The offset unit may 
+ *  be in one of PS_ARCSEC, PS_ARCMIN, PS_DEGREE, and PS_RADIAN, which 
+ *  specifies the units of the offset only.
+ *
+ *  @return psSphere*    the offset between position1 and position2
+ */
+psSphere* psSphereGetOffset(
+    const psSphere* restrict position1,
+    const psSphere* restrict position2,
+    psSphereOffsetMode mode,
+    psSphereOffsetUnit unit
+);
+
+/** Applies the given offset to a coordinate.
+ *
+ *  Both an offset mode and an offset unit may be defined. The mode may be 
+ *  either PS_SPHERICAL, in which case the specified offset corresponds to an 
+ *  offset in angles, or it may be PS_LINEAR, in which case the offset 
+ *  corresponds to a linear offset in a local projection. The offset unit may 
+ *  be in one of PS_ARCSEC, PS_ARCMIN, PS_DEGREE, and PS_RADIAN, which 
+ *  specifies the units of the offset only.
+ *
+ *  @return psSphere*    the given position with the given offset applied.
+ */
+psSphere* psSphereSetOffset(
+    const psSphere* restrict position,
+    const psSphere* restrict offset,
+    psSphereOffsetMode mode,
+    psSphereOffsetUnit unit
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/astronomy/psMetadata.c
===================================================================
--- /branches/rel3/psLib/src/astronomy/psMetadata.c	(revision 2163)
+++ /branches/rel3/psLib/src/astronomy/psMetadata.c	(revision 2163)
@@ -0,0 +1,589 @@
+
+/** @file  psMetadata.c
+*
+*
+*  @brief Contains metadata structures, enumerations and functions prototypes.
+*
+*  This file defines metadata item, metadata type, metadata flags, metadata containers, and function
+*  prototypes necessary creating psLib metadata APIs
+*
+*  @ingroup Metadata
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.34 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-09 03:05:53 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include<stdio.h>
+#include<stdarg.h>
+#include<string.h>
+
+#include "fitsio.h"
+#include "psType.h"
+#include "psMemory.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psList.h"
+#include "psHash.h"
+#include "psVector.h"
+#include "psMetadata.h"
+#include "psString.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Maximum size of a string */
+#define MAX_STRING_LENGTH 1024
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+static int metadataId = 0;
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+static void metadataItemFree(psMetadataItem* metadataItem)
+{
+    psMetadataType type;
+
+    type = metadataItem->type;
+
+    if (metadataItem == NULL) {
+        return;
+    }
+
+    psFree(metadataItem->name);
+    psFree(metadataItem->comment);
+    psFree(metadataItem->items);
+
+    if (type == PS_META_STR || type == PS_META_VEC || type == PS_META_IMG || type == PS_META_JPEG ||
+            type == PS_META_PNG || type == PS_META_ASTROM || type == PS_META_UNKNOWN) {
+        psFree(metadataItem->data.V);
+    }
+}
+
+static void metadataFree(psMetadata* metadata)
+{
+    if (metadata == NULL) {
+        return;
+    }
+    psFree(metadata->list);
+    psFree(metadata->table);
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+psMetadataItem* psMetadataItemAlloc(const char *name, psMetadataType type, const char *comment, ...)
+{
+    va_list argPtr;
+    psMetadataItem* metadataItem = NULL;
+
+    // Get the variable list parameters to pass to allocation function
+    va_start(argPtr, comment);
+
+    // Call metadata item allocation
+    metadataItem = psMetadataItemAllocV(name, type, comment, argPtr);
+
+    // Clean up stack after variable arguement has been used
+    va_end(argPtr);
+
+    return metadataItem;
+}
+
+psMetadataItem* psMetadataItemAllocV(const char *name, psMetadataType type, const char *comment,
+                                     va_list argPtr)
+{
+    psVector *vecIn = NULL;
+    psVector *vecOut = NULL;
+    psMetadataItem* metadataItem = NULL;
+
+
+    if (name == NULL) {
+        psError(__func__, "Null value for name not allowed");
+        return NULL;
+    }
+    // Allocate metadata item
+    metadataItem = (psMetadataItem* ) psAlloc(sizeof(psMetadataItem));
+
+    // Set deallocator
+    p_psMemSetDeallocator(metadataItem, (psFreeFcn) metadataItemFree);
+
+    // Allocate and set metadata item comment
+    metadataItem->comment = (char *)psAlloc(sizeof(char) * MAX_STRING_LENGTH);
+    if (comment == NULL) {
+        // Per SDRS, null isn't allowed, must use "" instead
+        strncpy(metadataItem->comment, "", MAX_STRING_LENGTH);
+    } else {
+        strncpy(metadataItem->comment, comment, MAX_STRING_LENGTH);
+    }
+
+    // Set metadata item unique id
+    *(int *)(&metadataItem->id) = ++metadataId;
+
+    // Set metadata item type
+    metadataItem->type = type;
+
+    // Set metadata item value
+    switch (type) {
+    case PS_META_ITEM_SET:
+        metadataItem->data.V = NULL;
+        break;
+    case PS_META_BOOL:
+        metadataItem->data.B = (bool)va_arg(argPtr, int);
+        break;
+    case PS_META_S32:
+        metadataItem->data.S32 = (psS32)va_arg(argPtr, psS32);
+        break;
+    case PS_META_F32:
+        metadataItem->data.F32 = (psF32)va_arg(argPtr, psF64);
+        break;
+    case PS_META_F64:
+        metadataItem->data.F64 = va_arg(argPtr, psF64);
+        break;
+    case PS_META_STR:
+        metadataItem->data.V = psStringNCopy(va_arg(argPtr, char *), MAX_STRING_LENGTH);
+        break;
+    case PS_META_VEC:
+        vecIn = (psVector*)va_arg(argPtr, psVector*);
+        vecOut = psVectorAlloc(vecIn->nalloc, vecIn->type.type);
+        memcpy(vecOut->data.V, vecIn->data.V, vecIn->nalloc*PSELEMTYPE_SIZEOF(vecIn->type.type));
+        metadataItem->data.V = vecOut;
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+    default:
+        psError(__func__, "Invalid psMetadataType: %d", type);
+    }
+
+    // Allocate and set metadata item name
+    metadataItem->name = (char *)psAlloc(sizeof(char) * MAX_STRING_LENGTH);
+    vsprintf(metadataItem->name, name, argPtr);
+
+    // Allocate metadata items with same name.
+    metadataItem->items = psListAlloc(NULL);
+
+    return metadataItem;
+}
+
+psMetadata* psMetadataAlloc(void)
+{
+    psList* list = NULL;
+    psHash* table = NULL;
+    psMetadata* metadata = NULL;
+
+    // Allocate metadata
+    metadata = (psMetadata* ) psAlloc(sizeof(psMetadata));
+    // Set deallocator
+    p_psMemSetDeallocator(metadata, (psFreeFcn) metadataFree);
+
+    // Allocate metadata's internal containers
+    list = (psList* ) psListAlloc(NULL);
+
+    table = (psHash* ) psHashAlloc(10);
+
+    metadata->list = list;
+    metadata->table = table;
+
+    return metadata;
+}
+
+bool psMetadataAddItem( psMetadata *restrict md, psMetadataItem *restrict metadataItem, int location )
+{
+    char * key = NULL;
+    psHash *mdTable = NULL;
+    psList *mdList = NULL;
+    psMetadataItem *existingEntry = NULL;
+    psMetadataItem *newFolderEntry = NULL;
+    psMetadataType newType = PS_META_ITEM_SET;
+
+    if(md == NULL) {
+        psError( __func__, "Null metadata collection not allowed" );
+        return false;
+    }
+
+    if(metadataItem == NULL) {
+        psError( __func__, "Null metadata item not allowed" );
+        return false;
+    }
+
+    newType = metadataItem->type;
+
+    mdTable = md->table;
+    if(mdTable == NULL) {
+        psError( __func__, "Null metadata table not allowed" );
+        return false;
+    }
+
+    mdList = md->list;
+    if(mdList == NULL) {
+        psError( __func__, "Null metadata list not allowed");
+        return false;
+    }
+
+    key = metadataItem->name;
+    if(key == NULL) {
+        psError(__func__, "Null key item not allowed");
+        return false;
+    }
+
+    // See if key is already in table
+    existingEntry = (psMetadataItem*)psHashLookup(mdTable, key);
+    if(existingEntry != NULL) {
+
+        if(existingEntry->type == PS_META_ITEM_SET) {
+
+            // Add leaf node to existing folder node
+            if(!psListAdd(existingEntry->items, PS_LIST_TAIL, metadataItem)) {
+                psError( __func__, "Couldn't add metadata item to items list. Name: %s",
+                         metadataItem->name );
+                return false;
+            }
+        } else if(existingEntry->type != PS_META_ITEM_SET && newType!= PS_META_ITEM_SET) {
+
+            // Leaf node replaces another leaf. Make new folder node and add leaves.
+            newFolderEntry = psMetadataItemAlloc(key, PS_META_ITEM_SET, NULL, NULL);
+
+            if(!psListAdd(newFolderEntry->items, PS_LIST_TAIL, existingEntry)) {
+                psError( __func__, "Couldn't add metadata item to items list. Name: %s", key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psListAdd(newFolderEntry->items, PS_LIST_TAIL, metadataItem)) {
+                psError( __func__, "Couldn't add metadata item to items list. Name: %s", key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psHashRemove(mdTable, key)) {
+                psError( __func__, "Couldn't remove metadata item from metadata table. Name: %s", key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psHashAdd(mdTable, key, newFolderEntry)) {
+                psError( __func__, "Couldn't add metadata item to metadata table. Name: %s", key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            // Remove local reference to new folder node
+            psMemDecrRefCounter(newFolderEntry);
+        } else {
+
+            // Folder node replaces leaf or folder node - Put old node into new folder and remove from table
+            if(!psListAdd(metadataItem->items, PS_LIST_TAIL, existingEntry)) {
+                psError( __func__, "Couldn't add metadata item to items list. Name: %s", key);
+                return false;
+            }
+
+            if(!psHashRemove(mdTable, key)) {
+                psError( __func__, "Couldn't remove metadata item from metadata table. Name: %s", key);
+                return false;
+            }
+
+            if(!psHashAdd(mdTable, key, metadataItem)) {
+                psError( __func__, "Couldn't add metadata item to metadata table. Name: %s", key);
+                return false;
+            }
+        }
+    } else {
+
+        // Node doesn't exist - Add new metadata item to metadata collection's hash
+        if(!psHashAdd(mdTable, key, metadataItem)) {
+            psError( __func__, "Couldn't add metadata item to metadata table. Name: %s", key);
+            return false;
+        }
+    }
+
+    // Add items to metadata collection's list, even if they have the same metadata item names. Folder nodes
+    // (PS_META_ITEM_SET metadata items) are not added, since the metadata list is flat.
+    if(metadataItem->type != PS_META_ITEM_SET) {
+        if(!psListAdd(mdList, location, metadataItem)) {
+            psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s",
+                     metadataItem->name );
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool psMetadataAdd(psMetadata* restrict md, int where, const char *name, psMetadataType type,
+                   const char *comment, ...)
+{
+    va_list argPtr;
+    psMetadataItem* metadataItem = NULL;
+
+    va_start(argPtr, comment);
+    metadataItem = psMetadataItemAllocV(name, type, comment, argPtr);
+    va_end(argPtr);
+
+    if (!psMetadataAddItem(md, metadataItem, where)) {
+        psError(__func__, "Couldn't add metadata item to metadata collection list. Name: %s",
+                metadataItem->name);
+        psFree(metadataItem);
+        return false;
+    }
+    // Decrement reference count, since the metadata item is now in metadata collection and no longer needed
+    psMemDecrRefCounter(metadataItem);
+
+    return true;
+}
+
+bool psMetadataRemove(psMetadata* restrict md, int where, const char *restrict key)
+{
+    int numChildren = 0;
+    psList* mdList = NULL;
+    psHash* mdTable = NULL;
+    psMetadataItem* entry = NULL;
+    psMetadataItem* entryChild = NULL;
+
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return false;
+    }
+
+    mdList = md->list;
+    if (mdList == NULL) {
+        psError(__func__, "Null metadata list not allowed");
+        return false;
+    }
+
+    mdTable = md->table;
+    if (mdTable == NULL) {
+        psError(__func__, "Null metadata table not allowed");
+        return false;
+    }
+    // Select removal by key or index
+    if (key != NULL) {
+
+        // Remove by key name
+        entry = (psMetadataItem* ) psHashLookup(mdTable, key);
+        if (entry == NULL) {
+            psError(__func__, "Couldn't find metadata item. Name: %s", key);
+            return false;
+        }
+
+        numChildren = entry->items->size;
+        if (entry->type == PS_META_ITEM_SET && numChildren > 0) {
+
+            // Table entry has children. Entry and children must be removed from metadata collection's list
+            psListSetIterator(entry->items, PS_LIST_HEAD);
+            entryChild = psListGetCurrent(entry->items);
+            while (entryChild != NULL) {
+                if (!psListRemove(mdList, PS_LIST_UNKNOWN, entryChild)) {
+                    psError(__func__, "Couldn't remove metadata item from list. Name: %s", key);
+                    return false;
+                }
+                entryChild = psListGetNext(entry->items);
+            }
+        } else {
+
+            // Table entry has no children. Remove entry from metadata collection's list
+            if (!psListRemove(mdList, PS_LIST_UNKNOWN, entry)) {
+                psError(__func__, "Couldn't remove metadata item from list. Name: %s", key);
+                return false;
+            }
+        }
+        // Remove entry from metadata collection's table
+        if (!psHashRemove(mdTable, key)) {
+            psError(__func__, "Couldn't remove metadata item from table. Name: %s", key);
+            return false;
+        }
+    } else {
+
+        // Remove by index
+        entry = psListGet(mdList, where);
+        if (entry == NULL) {
+            psError(__func__, "Couldn't find metadata item in list. Index: %d", where);
+            return false;
+        }
+
+        key = entry->name;
+        if (key == NULL) {
+            psError(__func__, "Null key name not allowed. Index: %d", where);
+            return false;
+        }
+        // Use recursive remove, now that key is known
+        psMetadataRemove(md, PS_LIST_UNKNOWN, key);
+    }
+
+    return true;
+}
+
+psMetadataItem* psMetadataLookup(psMetadata* restrict md, const char *restrict key)
+{
+    psHash* mdTable = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return NULL;
+    }
+
+    mdTable = md->table;
+    if (mdTable == NULL) {
+        psError(__func__, "Null metadata table not allowed");
+        return NULL;
+    }
+
+    if (key == NULL) {
+        psError(__func__, "Null key name not allowed");
+        return NULL;
+    }
+
+    entry = (psMetadataItem* ) psHashLookup(mdTable, key);
+    if (entry == NULL) {
+        return NULL;
+    }
+
+    return entry;
+}
+
+psMetadataItem* psMetadataGet(psMetadata* restrict md, int where)
+{
+    psList* mdList = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return NULL;
+    }
+
+    mdList = md->list;
+    if (mdList == NULL) {
+        psError(__func__, "Null metadata list not allowed");
+        return NULL;
+    }
+
+    entry = (psMetadataItem* ) psListGet(mdList, where);
+    if (entry == NULL) {
+        psError(__func__, "Couldn't find metadata item with given index. Index: %d", where);
+        return NULL;
+    }
+
+    return entry;
+}
+
+bool psMetadataSetIterator(psMetadata* restrict md, int where)
+{
+    psList* mdList = NULL;
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return false;
+    }
+
+    mdList = md->list;
+    if (mdList == NULL) {
+        psError(__func__, "Null metadata list not allowed");
+        return false;
+    }
+
+    psListSetIterator(mdList, where);
+
+    return true;
+}
+
+psMetadataItem* psMetadataGetNext(psMetadata* restrict md, const char *restrict match, int which)
+{
+    psList* mdList = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return NULL;
+    }
+
+    mdList = md->list;
+    if (mdList == NULL) {
+        psError(__func__, "Null metadata list not allowed");
+        return NULL;
+    }
+
+    psListSetIterator(mdList, which);
+    entry = psListGetCurrent(mdList);
+    while (entry != NULL) {
+        if(match != NULL) {
+            if (!strncmp(match, entry->name, strlen(match))) {
+
+                // Match found
+                return entry;
+            }
+            entry = psListGetNext(mdList);
+        } else {
+            entry = psListGetNext(mdList);
+            break;
+        }
+    }
+
+    return entry;
+}
+
+psMetadataItem* psMetadataGetPrevious(psMetadata* restrict md, const char *restrict match, int which)
+{
+    psList* mdList = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return NULL;
+    }
+
+    mdList = md->list;
+    if (mdList == NULL) {
+        psError(__func__, "Null metadata list not allowed");
+        return NULL;
+    }
+
+    psListSetIterator(mdList, which);
+    entry = psListGetCurrent(mdList);
+    while (entry != NULL) {
+        if(match != NULL) {
+            if (!strncmp(match, entry->name, strlen(match))) {
+
+                // Match found
+                return entry;
+            }
+            entry = psListGetPrevious(mdList);
+        } else {
+            entry = psListGetPrevious(mdList);
+            break;
+        }
+    }
+
+    return entry;
+}
Index: /branches/rel3/psLib/src/astronomy/psMetadata.h
===================================================================
--- /branches/rel3/psLib/src/astronomy/psMetadata.h	(revision 2163)
+++ /branches/rel3/psLib/src/astronomy/psMetadata.h	(revision 2163)
@@ -0,0 +1,247 @@
+
+/** @file  psMetadata.h
+*
+*  @brief Contains metadata struuctures, enumerations and functions prototypes
+*
+*  This file defines metadata item, metadata type, metadata flags, metadata containers, and function
+*  prototypes necessary creating psLib metadata APIs
+*
+*  @ingroup Metadata
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.23 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-06 01:06:27 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#ifndef PS_METADATA_H
+#define PS_METADATA_H
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "psHash.h"
+#include "psList.h"
+
+/// @addtogroup Metadata
+/// @{
+
+/** Metadata item type.
+ *
+ * Enumeration for maintaining metadata item types.
+ */
+typedef enum {
+    PS_META_ITEM_SET = 0,              ///< Null. Metadata is in psMetadataItem.items
+    PS_META_BOOL,                      ///< Boolean data.
+    PS_META_S32,                       ///< Signed 32-bit integer data.
+    PS_META_F32,                       ///< Single-precision float data.
+    PS_META_F64,                       ///< Double-precision float data.
+    PS_META_STR,                       ///< String data (Stored in as void *).
+    PS_META_VEC,                       ///< Vector data (Stored in as void *).
+    PS_META_IMG,                       ///< Image data (Stored in as void *).
+    PS_META_JPEG,                      ///< JPEG data (Stored in as void *).
+    PS_META_PNG,                       ///< PNG data (Stored in as void *).
+    PS_META_ASTROM,                    ///< Astrometric coefficients (Stored in as void *).
+    PS_META_UNKNOWN,                   ///< Other data (Stored in as void *).
+    PS_META_NTYPE                      ///< Number of types. Must be last.
+} psMetadataType;
+
+/** Metadata item data structure.
+ *
+ * Struct for maintaining metadata items of varying types. It also contains
+ * information about the item name, flags, comments, and other items with the same name.
+ */
+typedef struct psMetadataItem
+{
+    const int id;                      ///< Unique ID for metadata item.
+    char *restrict name;               ///< Name of metadata item.
+    psMetadataType type;               ///< Type of metadata item.
+    union {
+        bool B;                        ///< boolean data
+        psS32 S32;                     ///< Signed 32-bit integer data.
+        psF32 F32;                     ///< Single-precision float data.
+        psF64 F64;                     ///< Double-precision float data.
+        psPTR V;                       ///< Pointer to other type of data.
+    } data;                            ///< Union for data types.
+    char *comment;                     ///< Optional comment ("", not NULL).
+    psList* restrict items;            ///< List of psMetadataItems with same name.
+}
+psMetadataItem;
+
+/** Metadata data structure.
+ *
+ *  Struct for holding metadata items. Metadata items are held in two
+ *  containers. The first employs a doubly-linked list to preserve the order
+ *  of the metadata. The second container employs a hash table which
+ *  allows fast lookup when given a metadata keyword.
+ */
+typedef struct psMetadata
+{
+    psList* restrict list;             ///< the metadata in linked-list
+    psHash* restrict table;            ///< the metadata in a hash table
+}
+psMetadata;
+
+/** Create a metadata item.
+ *
+ *  Returns a fill psMetadataItem ready for insertion into the psMetadata
+ *  struct. The name argument specifies the name to use for this item, and
+ *  may include sprintf formatting codes. The format entry specifies both
+ *  the metadata type and optional flags and is created by bit-wise or of the
+ *  appropriate type and flag. The comment argument is a fixed string used to
+ *  comment the metadata item. The arguments to the name formatting codes and
+ *  the metadata itself are passed as arguments following the comment string.
+ *  The data must be a pointer for any of the elements stored in data.void.
+ *  The argument list must be interpreted appropriately by the va_list
+ *  operators in the function specified size and type.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataItemAlloc(
+    const char *name,                  ///< Name of metadata item.
+    psMetadataType type,               ///< Type of metadata item.
+    const char *comment,               ///< Comment for metadata item.
+    ...                                ///< Arguments for name formatting and metadata item data.
+);
+
+/** Create a metadata item with va_list.
+ *
+ *  Returns a fill psMetadataItem ready for insertion into the psMetadata
+ *  struct. The name argument specifies the name to use for this item, and
+ *  may include sprintf formatting codes. The format entry specifies both
+ *  the metadata type and optional flags and is created by bit-wise or of the
+ *  appropriate type and flag. The comment argument is a fixed string used to
+ *  comment the metadata item. The arguments to the name formatting codes and
+ *  the metadata itself are passed as arguments following the comment string.
+ *  The data must be a pointer for any of the elements stored in data.void.
+ *  The argument list must be interpreted appropriately by the va_list
+ *  operators in the function specified size and type.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataItemAllocV(
+    const char *name,                  ///< Name of metadata item.
+    psMetadataType type,               ///< Type of metadata item.
+    const char *comment,               ///< Comment for metadata item.
+    va_list list                       ///< Arguments for name formatting and metadata item data.
+);
+
+/** Create a metadata collection.
+ *
+ *  Returns an empty metadata container with fully allocated internal metadata
+ *  containers.
+ *
+ *  @return psMetadata* : Pointer metadata.
+ */
+psMetadata* psMetadataAlloc(void);
+
+/** Add existing metadata item to metadata collection.
+ *
+ *  Add a metadata item that has already been created to the metadata
+ *  collection.
+ *
+ *  @return bool: True for success, false for failure.
+ */
+bool psMetadataAddItem(
+    psMetadata* restrict md,           ///< Metadata collection to insert metadat item.
+    psMetadataItem* restrict item,     ///< Metadata item to be added.
+    int location                       ///< Location to be added.
+);
+
+/** Create and add a metadata item to metadata collection.
+ *
+ * Creates a new metadata item add to the metadata collection.
+ *
+ * @return bool: True for success, false for failure.
+ */
+bool psMetadataAdd(
+    psMetadata* restrict md,           ///< Metadata collection to insert metadat item.
+    int where,                         ///< Location to be added.
+    const char *name,                  ///< Name of metadata item.
+    psMetadataType type,               ///< Type of metadata item.
+    const char *comment,               ///< Comment for metadata item.
+    ...                                ///< Arguments for name formatting and metadata item data.
+);
+
+/** Remove an item from metadata collection.
+ *
+ *  Items may be removed from metadata by specifing a key or location. If the
+ *  name is null, the where argument is used instead. If name is not null,
+ *  where is set to PS_LIST_UNKNOWN. If the item is found, it is removed from
+ *  the metadata and true is returned.  If the key is not unique, then all
+ *  items corresponding to it are removed.
+ *
+ * @return bool: True for success, false for failure.
+ */
+bool psMetadataRemove(
+    psMetadata* restrict md,           ///< Metadata collection to insert metadat item.
+    int where,                         ///< Location to be removed.
+    const char *restrict key           ///< Name of metadata key.
+);
+
+/** Find an item in the metadata collection based on key name.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the first item is returned. If the item is not found, null is
+ *  returned.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataLookup(
+    psMetadata* restrict md,           ///< Metadata collection to insert metadata item.
+    const char *restrict key           ///< Name of metadata key.
+);
+
+/** Find an item in the metadata collection based on list index.
+ *
+ *  Items may be found in the metadata by their entry position in the list
+ *  container.
+ *
+ *  @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataGet(
+    psMetadata* restrict md,           ///< Metadata collection to insert metadat item.
+    int where                          ///< Location to be retrieved.
+);
+
+/** Set or reset metadata iterator.
+ *
+ *  Metadata may be iterated by setting or resetting an iterator to a location
+ *  in the metadata list.
+ *
+ * @return void: void.
+ */
+bool psMetadataSetIterator(
+    psMetadata* restrict md,           ///< Metadata collection to iterate.
+    int where                          ///< Location of iterator.
+);
+
+/** Get next metadata item.
+ *
+ * Get next metadata item in iterator list.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataGetNext(
+    psMetadata* restrict md,           ///< Metadata collection to iterate.
+    const char *restrict match,        ///< Beginning of key name.
+    int which                          ///< Iterator to be used.
+);
+
+/** Get previous metadata item.
+ *
+ * Get previous metadata item in iterator list.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataGetPrevious(
+    psMetadata* restrict md,           ///< Metadata collection to iterate.
+    const char *restrict match,        ///< Beginning of key name.
+    int which                          ///< Iterator to be used.
+);
+
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/astronomy/psMetadataIO.c
===================================================================
--- /branches/rel3/psLib/src/astronomy/psMetadataIO.c	(revision 2163)
+++ /branches/rel3/psLib/src/astronomy/psMetadataIO.c	(revision 2163)
@@ -0,0 +1,662 @@
+/** @file  psMetadataIO.c
+*
+*  @brief Contains metadata input/output functions.
+*
+*  This file defines functions to read and write metadata to/from an external file.
+*
+*  @ingroup Metadata
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-08 00:43:12 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include <fitsio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "psAbort.h"
+#include "psType.h"
+#include "psMemory.h"
+#include "psError.h"
+#include "psString.h"
+#include "psList.h"
+#include "psHash.h"
+#include "psVector.h"
+#include "psMetadata.h"
+#include "psMetadataIO.h"
+
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Check for FITS errors */
+#define FITS_ERROR(STRING,PS_ERROR) \
+fits_get_errstatus(status, fitsErr); \
+psError(__func__, STRING, PS_ERROR, fitsErr); \
+status = 0; \
+fits_close_file(fd, &status); \
+if(status){ \
+    fits_get_errstatus(status, fitsErr); \
+    psError(__func__, "Couldn't close FITS file. FITS error: %s", fitsErr); \
+} \
+status = 0; \
+psFree(output); \
+return NULL;
+
+/** Free and null temporary variables used by config file parser */
+#define CLEAR_TEMPS()                                                                                        \
+if(strName) {                                                                                            \
+    psFree(strName);                                                                                     \
+    strName = NULL;                                                                                      \
+}                                                                                                        \
+if(strType) {                                                                                            \
+    psFree(strType);                                                                                     \
+    strType = NULL;                                                                                      \
+}                                                                                                        \
+if(strValue) {                                                                                           \
+    psFree(strValue);                                                                                    \
+    strValue = NULL;                                                                                     \
+}                                                                                                        \
+if(strComment) {                                                                                         \
+    psFree(strComment);                                                                                  \
+    strComment = NULL;                                                                                   \
+}                                                                                                        \
+if(tempVec) {                                                                                            \
+    psFree(tempVec);                                                                                     \
+    tempVec = NULL;                                                                                      \
+}
+
+/** Maximum size of a FITS line */
+#define FITS_LINE_SIZE 80
+
+/** Maximum size of a string */
+#define MAX_STRING_LENGTH 256
+
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+
+/** Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string
+ *  must be null terminated. */
+bool ignoreLine(char *inString)
+{
+    while(*inString!='\0' && *inString!='#') {
+        if(!isspace(*inString)) {
+            return false;
+        }
+        inString++;
+    }
+
+    return true;
+}
+
+
+/** Removes leading and trailing whitespace and # characters from a string. The cleaned string is a new null
+ *  terminated copy of the original input string. */
+char *cleanString(char *inString, int sLen)
+{
+    char *ptrB = NULL;
+    char *ptrE = NULL;
+    char *cleaned = NULL;
+
+
+    ptrB = inString;
+
+    /* Skip over leading # or whitespace */
+    while (isspace(*ptrB) || *ptrB=='#') {
+        ptrB++;
+    }
+
+    /* Skip over trailing whitespace, null terminators, and # characters */
+    ptrE = inString + sLen;
+    while(isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') {
+        ptrE--;
+    }
+
+    // Length, sLen, does not include '\0'
+    sLen = ptrE - ptrB + 1;
+
+    // Adds '\0' to end of string and +1 to sLen
+    cleaned = psStringNCopy(ptrB, sLen);
+
+    return cleaned;
+}
+
+/** Count repeat occurances of a single character within a line. The input string must be null terminated. */
+int repeatedChars(char *inString, char ch)
+{
+    int count = 0;
+
+
+    while(*inString!='\0') {
+        if(*inString == ch) {
+            count++;
+        }
+        inString++;
+    }
+
+    return count;
+}
+
+/** Returns cleaned token based on delimiter, but not including delimiter. Also changes the pointer location
+ * the beginning of the string. Tokens are newly allocated null terminated strings. */
+char* getToken(char **inString, char *delimiter, int *status)
+{
+    char *cleanToken = NULL;
+    int sLen = 0;
+
+
+    // Skip over leading whitespace
+    while(isspace(**inString)) {
+        (*inString)++;
+    }
+
+    // Length of token, not including delimiter
+    sLen = strcspn(*inString, delimiter);
+    if(sLen) {
+
+        // Create new, cleaned, and null terminated token
+        cleanToken = cleanString(*inString, sLen);
+
+        // Move to end of token
+        (*inString) += sLen;
+    } else if(**inString!='\0' && sLen==0) {
+        *status = 1;
+    }
+
+    return cleanToken;
+}
+
+/** Returns single parsed value as a double precision number. The input string must be cleaned and null
+ * terminated. */
+double parseValue(char *inString, int *status)
+{
+    char *end = NULL;
+    double value = 0.0;
+
+
+    value = strtod(inString, &end);
+    if(*end != '\0') {
+        *status = 1;
+    } else if(inString==end) {
+        *status = 1;
+    }
+
+    return value;
+}
+
+/** Returns true or false. 'T', 't', '1', 'F', 'f', and '0' are acceptable, parsable variations. */
+bool parseBool(char *inString, int *status)
+{
+    bool value = false;
+
+
+    if(*inString=='T' || *inString=='t' || *inString=='1') {
+        value = true;
+    } else if(*inString=='F' || *inString=='f' || *inString=='0') {
+        value = false;
+    } else {
+        *status = 1;
+    }
+
+    return value;
+}
+
+/** Returns parsed vector filled with with data. The input string must be null terminated. */
+psVector* parseVector(char *inString, psElemType elemType, int *status)
+{
+    char *end = NULL;
+    char *saveValue = NULL;
+    int i = 0;
+    int numValues = 0;
+    double value = 0.0;
+    psVector *vec = NULL;
+
+
+    // Cycle through string and count entries
+    saveValue = inString;
+    while(*inString!='\0') {
+        strtod(inString, &end);
+        if(inString==end) {
+            *status = 1;
+            return NULL;
+        }
+        while(*end==' ' || *end==',') { // Commas or spaces may be used as delimiters for vector values
+            end++;
+        }
+        inString=end;
+        numValues++;
+    }
+
+    // Cycle through string and convert string values to values
+    if(numValues) {
+        inString = saveValue;
+        end = NULL;
+        vec = psVectorAlloc(numValues, elemType);
+
+        while(*inString!='\0') {
+            value = strtod(inString, &end);
+            if(inString==end) {
+                *status = 1;
+                return vec;
+            }
+            switch(elemType) {
+            case PS_TYPE_U8:
+                vec->data.U8[i++] = (psU8)value;
+                break;
+            case PS_TYPE_S32:
+                vec->data.S32[i++] = (psS32)value;
+                break;
+            case PS_TYPE_F32:
+                vec->data.F32[i++] = (psF32)value;
+                break;
+            case PS_TYPE_F64:
+                vec->data.F64[i++] = (psF64)value;
+                break;
+            default:
+                *status = 1;
+                psError(__func__, "Invalid type: %d", elemType);
+            }
+
+            while(*end==' ' || *end==',') {
+                end++;
+            }
+            inString=end;
+        }
+    }
+
+    return vec;
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+void psMetadataItemPrint(FILE * fd, const char *format, const psMetadataItem* restrict metadataItem)
+{
+    psMetadataType type;
+
+    if (fd == NULL) {
+        psError(__func__, "Null file descriptor not allowed");
+        return;
+    }
+
+    if (format == NULL) {
+        psError(__func__, "Null format not allowed");
+        return;
+    }
+
+    if (metadataItem == NULL) {
+        psError(__func__, "Null metadata not allowed");
+        return;
+    }
+
+    type = metadataItem->type;
+
+    switch(type) {
+    case PS_META_BOOL:
+        fprintf(fd, format, metadataItem->data.B);
+        break;
+    case PS_META_S32:
+        fprintf(fd,format, metadataItem->data.S32);
+        break;
+    case PS_META_F32:
+        fprintf(fd, format, metadataItem->data.F32);
+        break;
+    case PS_META_F64:
+        fprintf(fd, format, metadataItem->data.F64);
+        break;
+    case PS_META_STR:
+        fprintf(fd, format, metadataItem->data.V);
+        break;
+    default:
+        psError(__func__, " Invalid psMetadataType to print: %d", type);
+    }
+}
+
+
+psMetadata* psMetadataReadHeader(psMetadata* output, char *extName, int extNum, char *fileName)
+{
+    bool tempBool;
+    bool success;
+    char keyType;
+    char keyName[FITS_LINE_SIZE];
+    char keyValue[FITS_LINE_SIZE];
+    char keyComment[FITS_LINE_SIZE];
+    char fitsErr[MAX_STRING_LENGTH];
+    int i;
+    int hduType = 0;
+    int status = 0;
+    int numKeys = 0;
+    int keyNum = 0;
+    psMetadataType metadataItemType;
+    fitsfile *fd = NULL;
+
+    if(fileName == NULL) {
+        psError(__func__, "Null fileName not allowed");
+        return NULL;
+    }
+
+    fits_open_file(&fd, fileName, READONLY, &status);
+    if(fd == NULL || status != 0) {
+        FITS_ERROR("FITS error while opening file: %s %s", fileName);
+        return NULL;
+    }
+
+    if (extName == NULL && extNum == 0) {
+        psError(__func__, "Null extName and extNum = 0 not allowed");
+        return NULL;
+    } else if (extName && (extNum != -1) ) {
+        psError(__func__, "If extName specified, extNum arguments should be -1.");
+        return NULL;
+    }
+
+    // Allocate metadata if user didn't
+    if (output == NULL) {
+        output = psMetadataAlloc();
+    }
+
+    // Move to user designated HDU number or HDU name in FITS file. HDU numbers starts at one.
+    if (extName != NULL) {
+        if (fits_movnam_hdu(fd, ANY_HDU, extName, 0, &status) != 0) {
+            FITS_ERROR("FITS error while locating header %s: %s", extName);
+        }
+    } else {
+        if (fits_movabs_hdu(fd, extNum, &hduType, &status) != 0) {
+            FITS_ERROR("FITS error while locating header %d: %s", extNum);
+        }
+    }
+
+    // Get number of key names
+    if (fits_get_hdrpos(fd, &numKeys, &keyNum, &status) != 0) {
+        FITS_ERROR("FITS error while reading key %d: %s", keyNum);
+    }
+
+    // Get each key name. Keywords start at one.
+    for (i = 1; i <= numKeys; i++) {
+        if (fits_read_keyn(fd, i, keyName, keyValue, keyComment, &status) != 0) {
+            FITS_ERROR("FITS error while reading key %d: %s", keyNum);
+        }
+        if (fits_get_keytype(keyValue, &keyType, &status) != 0) {
+            fits_get_errstatus(status, fitsErr);
+            if (status != VALUE_UNDEFINED) {
+                FITS_ERROR("FITS error while determining key %d type: %s", keyNum);
+            } else {
+                // Some keywords are still valid if they don't have a type (like COMMENTS and HISTORY)
+                keyType = 'C';
+                status = 0;
+            }
+        }
+
+        switch (keyType) {
+        case 'I':
+            metadataItemType = PS_META_S32;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, metadataItemType, keyComment, atoi(keyValue));
+            break;
+        case 'F':
+            metadataItemType = PS_META_F64;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, metadataItemType, keyComment, atof(keyValue));
+            break;
+        case 'C':
+            metadataItemType = PS_META_STR;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, metadataItemType, keyComment, keyValue);
+            break;
+        case 'L':
+            metadataItemType = PS_META_BOOL;
+            tempBool = (keyValue[0] == 'T') ? 1 : 0;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, metadataItemType, keyComment, tempBool);
+            break;
+        case 'U':
+        case 'X':
+        default:
+            psError(__func__, "Invalid psMetadataType: %c", keyType);
+            return output;
+        }
+
+        if (!success) {
+            psError(__func__, "Failed to add metadata item. Name: %s", keyName);
+            return output;
+        }
+    }
+
+    return output;
+}
+
+
+int psMetadataParseConfig(psMetadata** md, char *fileName, bool overwrite)
+{
+    bool tempBool;
+    char *line = NULL;
+    char *strName = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    char *strComment = NULL;
+    char *linePtr = NULL;
+    int status = 0;
+    int lineCount = 0;
+    int failedLines = 0;
+    psF64 tempDbl = 0.0;
+    psS32 tempInt = 0.0;
+    psMetadataItem *metadataItem = NULL;
+    psVector *tempVec = NULL;
+    FILE *fp = NULL;
+    psElemType elemType;
+    psMetadataType mdType;
+
+
+    // Check for nulls
+    if(fileName == NULL) {
+        psError(__func__, "Null fileName not allowed");
+        return -1;
+    } else if((fp=fopen(fileName, "r")) == NULL) {
+        psError(__func__, "Couldn't open file. Name: %s", fileName);
+        return -1;
+    }
+
+    // Allocate metadata if necessary
+    if (*md == NULL) {
+        *md = psMetadataAlloc();
+    }
+
+    // Create reusable line for continuous read
+    line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char));
+    if (line == NULL) {
+        psAbort(__func__, "Failed to allocate reusable line");
+    }
+
+    // While loop to parse the file
+    while(fgets(line, MAX_STRING_LENGTH, fp) != NULL) {
+
+        // Initialize variables for new line
+        linePtr = line;
+        lineCount++;
+        CLEAR_TEMPS();
+
+        // If line is not a comment or blank, then extract data
+        if(!ignoreLine(linePtr)) {
+
+            // Check for more than one '*' or '@' in a line
+            if(repeatedChars(linePtr, '@') > 1) {
+                failedLines++;
+                psError(__func__, "More than one @ charecter not allowed. Line %d: %s", lineCount, line);
+                continue;
+            } else if(repeatedChars(linePtr, '*') > 1) {
+                failedLines++;
+                psError(__func__, "More than one * charecter not allowed. Line %d: %s", lineCount, line);
+                continue;
+            } else if(repeatedChars(linePtr, '~') > 0) {
+                failedLines++;
+                psError(__func__, "Illegal character. Character:~ Line %d: %s", lineCount, line);
+                continue;
+            }
+
+            // Get metadata item name
+            strName = getToken(&linePtr, " ", &status);
+            if(strName==NULL || status) {
+                failedLines++;
+                status = 0;
+                psError(__func__, "Null name not allowed. Line %d: %s", lineCount, line);
+                continue;
+            }
+
+            // Get the metadata item type
+            strType = getToken(&linePtr, " ", &status);
+            if(strType==NULL) {
+                failedLines++;
+                status = 0;
+                psError(__func__, "Null type not allowed. Line %d: %s", lineCount, line);
+                continue;
+            } else if(!strncmp(strType, "*", 1)) {
+                mdType = PS_META_ITEM_SET;
+            } else if(!strncmp(strType, "STR", 3)) {
+                mdType = PS_META_STR;
+                elemType = PS_TYPE_PTR;
+            } else if(!strncmp(strType, "BOOL", 3)) {
+                mdType = PS_META_BOOL;
+                elemType = PS_TYPE_U8;
+            } else if(!strncmp(strType, "S32", 3)) {
+                mdType = PS_META_S32;
+                elemType = PS_TYPE_S32;
+            } else if(!strncmp(strType, "F32", 3)) {
+                mdType = PS_META_F32;
+                elemType = PS_TYPE_F32;
+            } else if(!strncmp(strType, "F64", 3)) {
+                mdType = PS_META_F64;
+                elemType = PS_TYPE_F64;
+            } else {
+                failedLines++;
+                psError(__func__, "Invalid psMetadataType. Type: %s Line %d: %s", strType, lineCount, line);
+                continue;
+            }
+
+            if(*strName == '@') {
+                mdType = PS_META_VEC;
+            }
+
+            // Get the metadata item value if there is one. Lines with * don't have values.
+            if(mdType != PS_META_ITEM_SET) {
+                strValue = getToken(&linePtr, "#", &status);
+                if(strValue==NULL) {
+                    failedLines++;
+                    status = 0;
+                    psError(__func__, "Null value not allowed. Line %d: %s", lineCount, line);
+                    continue;
+                }
+            }
+
+            // Get the metadata item value if there is one. Not all lines will have comments, so NULL is ok.
+            strComment = getToken(&linePtr,"~", &status);
+            if(status) {
+                failedLines++;
+                status = 0;
+                psError(__func__, "Failed to parse comment. Line %d: %s", lineCount, line);
+                continue;
+            }
+
+            /* If metadata item is found, is not a folder node, and overwrite is allowed, then remove existing
+            and allow switch/case below to add new item. If overwrite is false, then report error. If found
+            item is folder node, then psMetadataAdd will automatically add a new child. */
+            metadataItem = psMetadataLookup(*md, strName);
+            if(metadataItem != NULL) {
+                if(metadataItem->type!=PS_META_ITEM_SET) {
+                    if(overwrite) {
+                        psMetadataRemove(*md, PS_LIST_UNKNOWN, strName);
+                    } else {
+                        failedLines++;
+                        psError(__func__, "Overwrite for name not allowed. Name: %s. Line %d: %s", strName,
+                                lineCount, line);
+                        continue;
+                    }
+                }
+            }
+
+            // Create and add metadata item to metadata and parse values
+            switch (mdType) {
+            case PS_META_ITEM_SET:
+                psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, NULL, NULL);
+                break;
+            case PS_META_BOOL:
+                tempBool = parseBool(strValue, &status);
+                if(!status) {
+                    psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, strComment, tempBool);
+                } else {
+                    status = 0;
+                    failedLines++;
+                    psError(__func__, "Failed to parse value. Value: %s Line %d: %s", strValue, lineCount, line);
+                    continue;
+                }
+                break;
+            case PS_META_S32:
+                tempInt = (psS32)parseValue(strValue, &status);
+                if(!status) {
+                    psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, strComment, tempInt);
+                } else {
+                    status = 0;
+                    failedLines++;
+                    psError(__func__, "Failed to parse value. Value: %s Line %d: %s", strValue, lineCount, line);
+                    continue;
+                }
+                break;
+            case PS_META_F32:
+            case PS_META_F64:
+                tempDbl = parseValue(strValue, &status);
+                if(!status) {
+                    psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, strComment, tempDbl);
+                } else {
+                    status = 0;
+                    failedLines++;
+                    psError(__func__, "Failed to parse value. Value: %s Line %d: %s", strValue, lineCount, line);
+                    continue;
+                }
+                break;
+            case PS_META_STR:
+                psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, strComment, strValue);
+                break;
+            case PS_META_VEC:
+                tempVec = parseVector(strValue, elemType, &status);
+                if(!status) {
+                    psMetadataAdd(*md, PS_LIST_TAIL, strName+1, mdType, strComment, tempVec);
+                } else {
+                    status = 0;
+                    failedLines++;
+                    psError(__func__, "Failed to parse value. Value: %s Line %d: %s", strValue, lineCount, line);
+                    continue;
+                }
+                break;
+            default:
+                failedLines++;
+                psError(__func__, "Invalid psMetadataType. Type: %d Line %d: %s", mdType, lineCount, line);
+                continue;
+            } // switch
+        } // if ignoreLine
+    } // while loop
+
+    psFree(line);
+
+    return failedLines;
+}
Index: /branches/rel3/psLib/src/astronomy/psMetadataIO.h
===================================================================
--- /branches/rel3/psLib/src/astronomy/psMetadataIO.h	(revision 2163)
+++ /branches/rel3/psLib/src/astronomy/psMetadataIO.h	(revision 2163)
@@ -0,0 +1,70 @@
+/** @file  psMetadataIO.h
+*
+*  @brief Contains metadata input/output functions.
+*
+*  This file defines functions to read and write metadata to/from an external file.
+*
+*  @ingroup Metadata
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-06 01:17:39 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#ifndef PS_METADATAIO_H
+#define PS_METADATAIO_H
+
+
+/// @addtogroup Metadata
+/// @{
+
+
+/** Print metadata item to file.
+ *
+ *  Metadata items may be printed to an open file descriptor based on a
+ *  provided format. The format is a sprintf format statement with exactly
+ *  one % formatting command. If the metadata item type is a numeric type,
+ *  this formatting command must also be numeric, and the type conversion
+ *  performed to the value to match the format type. If the metadata type is
+ *  a string, the fromatting command must also be for a string. If the
+ *  metadata type is any other data type, printing is not allowed.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+void psMetadataItemPrint(
+    FILE * fd,                         ///< Pointer to file to write metadata item.
+    const char *format,                ///< Format to print metadata item.
+    const psMetadataItem* restrict metadataItem ///< Metadata item to print.
+);
+
+/** Read metadata header.
+ *
+ *  Read a metadata header from file. If the file is not found, an error is
+ *  reported.
+ *
+ *  @return psMetadata* : Pointer to resulting metadata.
+ */
+psMetadata* psMetadataReadHeader(
+    psMetadata* output,                ///< Resulting metadata from read.
+    char *extName,                     ///< File name extension string.
+    int extNum,                        ///< File name extension number. Starts at 1.
+    char *fileName                     ///< Name of file to read.
+);
+
+/** Read metadata configuration file.
+ *
+ *  Loads pre-defined settings by parsing a configuration file into a psMetadata structure.
+ *
+ *  @return int : Number of lines that failed to be read.
+ */
+int psMetadataParseConfig(
+    psMetadata** md,                   ///< Resulting metadata from read.
+    char *fileName,                    ///< Name of file to read.
+    bool overwrite                     ///< Allow overwrite of duplicate specifications.
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/astronomy/psPhotometry.h
===================================================================
--- /branches/rel3/psLib/src/astronomy/psPhotometry.h	(revision 2163)
+++ /branches/rel3/psLib/src/astronomy/psPhotometry.h	(revision 2163)
@@ -0,0 +1,75 @@
+
+/** @file  psPhotometry.h
+*
+*  @brief Contains basic photometric structures.
+*
+*  This file defines the basic photometric structures.
+*
+*  @ingroup Photometry
+*
+*  @author George Gusciora, MHPCC
+*
+*  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-08-09 23:40:54 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#ifndef PS_PHOTOMETRIC_H
+#define PS_PHOTOMETRIC_H
+
+#include "psType.h"
+#include "psImage.h"
+#include "psArray.h"
+#include "psList.h"
+#include "psFunctions.h"
+
+/// @addtogroup Photometry
+/// @{
+
+/** The photometric system description
+ *
+ *  The photometric system is defined by the psPhotSystem structure. A 
+ *  photometric system is identified by a human-readable name (ie, SDSS.g, 
+ *  Landolt92.B, GPC1.OTA32.r). Each photometric system is given a unique 
+ *  identifier ID. Observations taken with a specific camera, detector, and 
+ *  filter represent their own photometric system, and it may be necessary to 
+ *  perform transformations between these systems. Photometric systems 
+ *  associated with observations from a specific camera/ detector/filter 
+ *  combination can be associated with those components.
+ *
+ */
+
+typedef struct
+{
+    const int ID;               ///< ID number for this photometric system
+    const char *name;           ///< Name of photometric system
+    const char *camera;         ///< Camera for photometric system
+    const char *filter;         ///< Filter used for photometric system
+    const char *detector;       ///< Detector used for photometric system
+}
+psPhotSystem;
+
+/** Photometric system transformation
+ *
+ *  This structure defines the transformation between two photometric systems.
+ *
+ */
+
+typedef struct
+{
+    psPhotSystem src;           ///< Source photometric system
+    psPhotSystem dst;           ///< Destination photometric system
+    psPhotSystem pP;            ///< Primary color reference
+    psPhotSystem pM;            ///< Primary color reference
+    psPhotSystem sP;            ///< Secondary color reference
+    psPhotSystem sM;            ///< Secondary color reference
+    float pA;                   ///< Color offset for references
+    float sA;                   ///< Color offset for references
+    psPolynomial3D transform;   ///< Transformation from source to destination
+}
+psPhotTransform;
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/astronomy/psTime.c
===================================================================
--- /branches/rel3/psLib/src/astronomy/psTime.c	(revision 2163)
+++ /branches/rel3/psLib/src/astronomy/psTime.c	(revision 2163)
@@ -0,0 +1,1085 @@
+/** @file  psTime.c
+ *
+ *  @brief Definitions for time, time utilities, and conversion functions for use with psLib astronomy
+ *  functions.
+ *
+ *  A collection of functions are required by psLib to manipulate time data. These functions primarily consist
+ *  of conversions between specific time formats.  PSLib currently uses the UNIX timeval time system as the
+ *  base upon which International Atomic Time (TAI) and Universal Time Coordinated (UTC) are calculated. TAI
+ *  time varies over time due to the earth's rotation and the movement of the continental plates.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.34 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-15 19:10:50 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "psTime.h"
+#include "psError.h"
+#include "psMemory.h"
+#include "psAbort.h"
+#include "psImage.h"
+#include "psCoord.h"
+#include "psString.h"
+
+#include "psAstronomyErrors.h"
+
+#ifndef SER7_FILE
+#define SER7_FILE "../../data/ser7.dat"
+#pragma warning SER7_FILE was not defined in the makefile.
+#endif
+
+#ifndef TAIUTC_FILE
+#define TAIUTC_FILE "../../data/tai-utc.dat"
+#pragma warning TAIUTC_FILE was not defined in the makefile.
+#endif
+
+/** Sidereal angular conversion from seconds to radians for GMST in seconds (i.e. pi/(180*240)) */
+#define S2R (7.272205216643039903848711535369e-5)
+
+/** Two times pi with double precision accuracy */
+#define TWOPI (2.0*M_PI)
+
+/** Conversion from radians to degrees */
+#define R2DEG = (180.0/M_PI)
+
+                /** Maximum length of time string */
+                #define MAX_TIME_STRING_LENGTH 256
+
+                /** Seconds per minute */
+                #define  SEC_PER_MINUTE 60.0
+
+                /** Seconds per hour */
+                #define  SEC_PER_HOUR (60.0*SEC_PER_MINUTE)
+
+                /** Seconds per day */
+                #define  SEC_PER_DAY (24.0*SEC_PER_HOUR)
+
+                /** Seconds per year */
+                #define  SEC_PER_YEAR (365.0*SEC_PER_DAY)
+
+                /** Microseconds per day */
+                #define USEC_PER_DAY 86400000000.0
+
+                /** Max size of a line read */
+                #define LINESIZE 1024
+
+                /** Preprocessor macro to check for null psTime struct */
+                #define CHECK_NULL_TIME(TIME,RETURN) \
+                if(TIME == NULL) { \
+                    psError(__func__,"NULL value not allowed"); \
+                    return RETURN; \
+                }
+
+                /** Preprocessor macro to allocate psTime struct */
+                #define ALLOC_TIME(TIME) \
+                TIME = (psTime*)psAlloc(sizeof(psTime)); \
+if (TIME == NULL) { \
+    psAbort(__func__, " : Line %d - Failed to allocate memory", __LINE__); \
+} \
+TIME->sec = 0; \
+TIME->usec = 0; \
+TIME->type = PS_TIME_TAI;
+
+/** Read TAI/UTC data file.
+ *
+ *  Reads TAI/UTC data file.
+ *
+ *  @return  psImage*: Two-dimensional array with table data.
+ */
+static psImage* readTaiUtcFile(
+    const char *fileName                      ///< Name of file to read.
+);
+
+
+/** Read SER7 data file.
+ *
+ *  Reads SER7 data file.
+ *
+ *  @return  psImage*: Two-dimensional array with table data.
+ */
+static psImage* readSer7File(
+    const char *fileName                      ///< Name of file to read.
+);
+
+
+/** Read finals data file.
+ *
+ *  Reads finals data file.
+ *
+ *  @return  psImage*: Two-dimensional array with table data.
+ */
+/* not yet used
+static psImage* readFinalsFile(
+    char *fileName                      ///< Name of file to read.
+);
+*/
+
+/** Read EOPC data file.
+ *
+ *  Reads EOPC data file.
+ *
+ *  @return  psImage*: Two-dimensional array with table data.
+ */
+/* not yet used
+static psImage* readEopcFile(
+    char *fileName                      ///< Name of file to read.
+);
+*/
+
+/** Lookup and interpolate TAI-UTC data
+ *
+ *  Interpolates TAI-UTC data, given time in MJD format.
+ *
+ *  @return  double: Interpolated value.
+ */
+static double lookupTaiUtcTable(
+    const psTime *time                        ///< time to lookup.
+);
+
+/** Lookup and interpolate polar or UT1-UTC data
+ *
+ *  Interpolates TAI-UT1 or polar coordinate data, given time in MJD format.
+ *
+ *  @return  double: Interpolated value.
+ */
+static double lookupSer7Table(
+    const psTime *time,                        ///< time to lookup.
+    int col                              ///< Column to lookup.
+);
+
+static psImage* readTaiUtcFile(const char *fileName)
+{
+    char line[LINESIZE];
+    int j = 0;
+    int maxLines = 100;
+    psF64 *ptr = NULL;
+    psImage *table = NULL;
+    FILE *fd = NULL;
+
+
+    fd=fopen(fileName, "r");
+    if(fd==NULL) {
+        psError(__func__, " : Line %d - Couldn't open %s", __LINE__, fileName);
+        return NULL;
+    }
+
+    // Table shouldn't be larger than 100 rows. Select columns are read based on indices.
+    table  = psImageAlloc(4, maxLines, PS_TYPE_F64);
+
+    while(fgets(line, LINESIZE, fd) != NULL) {
+        if(j>=maxLines) {
+            psError(__func__, " : Line %d - Too many rows in file. Max size: %d", __LINE__, maxLines);
+            return NULL;
+            psFree(table);
+        }
+
+        ptr = table->data.F64[j++];
+        *ptr = atof(line+16);                  // MJD
+        *(ptr+1) = atof(line+38);              // TAI-UTC
+        *(ptr+2) = atof(line+59);              // Contant #1
+        *(ptr+3) = atof(line+69);              // Contant #2
+    }
+
+    *(unsigned int *)&table->numRows = j;
+
+    p_psMemSetPersistent(table,true);
+    p_psMemSetPersistent(table->data.V,true);
+    p_psMemSetPersistent(table->rawDataBuffer,true);
+
+    return table;
+}
+
+static psImage* readSer7File(const char *fileName)
+{
+    bool beginRecord = false;
+    char line[LINESIZE];
+    int j = 0;
+    int maxLines = 400;
+    psImage *table = NULL;
+    FILE *fd = NULL;
+
+
+    fd=fopen(fileName, "r");
+    if(fd==NULL) {
+        psError(__func__, " : Line %d - Couldn't open %s", __LINE__, fileName);
+        return NULL ;
+    }
+
+    // Table shouldn't be larger than 400 rows. All columns in area of interest are read.
+    table  = psImageAlloc(7, maxLines, PS_TYPE_F64);
+
+    while(fgets(line, LINESIZE, fd) != NULL) {
+
+        // Stop parsing after finding "These" in data file after read has began
+        if(beginRecord) {
+            if(strstr(line, "These")!=NULL) {
+                beginRecord = false;
+                break;
+            }
+
+            if(j>=maxLines) {
+                psError(__func__, " : Line %d - Too many rows in file. Max size: %d", __LINE__, maxLines);
+                return NULL;
+                psFree(table);
+            }
+            psF64 *ptr = table->data.F64[j++];
+            sscanf(line, "%lf %lf %lf %lf %lf %lf %lf", ptr, ptr+1, ptr+2, ptr+3, ptr+4, ptr+5, ptr+6);
+        }
+
+        // Start parsing after finding "x(arcsec)" in data file
+        if(strstr(line, "x(arcsec)") != NULL) {
+            beginRecord = true;
+        }
+    }
+    *(unsigned int *)&table->numRows = j;
+
+    p_psMemSetPersistent(table,true);
+    p_psMemSetPersistent(table->data.V,true);
+    p_psMemSetPersistent(table->rawDataBuffer,true);
+
+    return table;
+}
+
+/* Not yet used...
+static psImage* readEopcFile(char *fileName)
+{
+    char line[LINESIZE];
+    int i = 0;
+    int j = 0;
+    int maxLines = 2500;
+    psImage *table = NULL;
+    FILE *fd = NULL;
+ 
+ 
+    fd=fopen(fileName, "r");
+    if(fd==NULL) {
+        psError(__func__, " : Line %d - Couldn't open %s", __LINE__, fileName);
+        return NULL ;
+    }
+ 
+    // Table shouldn't be larger than 2500 rows. All columns are read.
+    table  = psImageAlloc(11, maxLines, PS_TYPE_F64);
+    for(i=0; i<3; i++) {
+        if((fgets(line, LINESIZE, fd) != NULL)) {
+            psError(__func__, " : Line %d - Error reading %s", __LINE__, fileName);
+        }
+    }
+ 
+    while(fgets(line, LINESIZE, fd) != NULL) {
+        if(j>=maxLines) {
+            psError(__func__, " : Line %d - Too many rows in file. Max size: %d", __LINE__, maxLines);
+            return NULL;
+            psFree(table);
+        }
+        psF64 *ptr = table->data.F64[j++];
+        sscanf(line, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
+               ptr, ptr+1, ptr+2, ptr+3, ptr+4, ptr+5, ptr+6, ptr+7, ptr+8, ptr+9, ptr+10);
+    }
+ 
+    *(unsigned int *)&table->numRows = j;
+ 
+    return table;
+}
+ 
+static psImage* readFinalsFile(char *fileName)
+{
+    char line[LINESIZE];
+    int j = 0;
+    int maxLines = 15000;
+    psImage *table = NULL;
+    FILE *fd = NULL;
+ 
+ 
+    fd=fopen(fileName, "r");
+    if(fd==NULL) {
+        psError(__func__, " : Line %d - Couldn't open %s", __LINE__, fileName);
+        return NULL ;
+    }
+ 
+    // Table shouldn't be larger than 15000 rows. Select columns are read.
+    table  = psImageAlloc(6, maxLines, PS_TYPE_F64);
+    while(fgets(line, LINESIZE, fd) != NULL) {
+        if(j>=maxLines) {
+            psError(__func__, " : Line %d - Too many rows in file. Max size: %d", __LINE__, maxLines);
+            return NULL;
+            psFree(table);
+        }
+ 
+        psF64 *ptr = table->data.F64[j++];
+        ptr = table->data.F64[j++];
+ 
+        // Sometimes there are blank entries in this table, so check for a space to determine if there is no entry
+        if(*(line+7) == ' ') {                   // MJD
+            *ptr = 0.0;
+        } else {
+            *ptr = atof(line+7);
+        }
+ 
+        if(*(line+18) == ' ') {                  // Polar motion X
+            *(ptr+1) = 0.0;
+        } else {
+            *(ptr+1) = atof(line+18);
+        }
+ 
+        if(*(line+27) == ' ') {                  // Polar motion X error
+            *(ptr+2) = 0.0;
+        } else {
+            *(ptr+2) = atof(line+27);
+        }
+ 
+        if(*(line+37) == ' ') {                  // Polar motion Y
+            *(ptr+3) = 0.0;
+        } else {
+            *(ptr+3) = atof(line+37);
+        }
+ 
+        if(*(line+46) == ' ') {                  // Polar motion Y error
+            *(ptr+4) = 0.0;
+        } else {
+            *(ptr+4) = atof(line+46);
+        }
+ 
+        if(*(line+58) == ' ') {                  // UT1-UTC
+            *(ptr+5) = 0.0;
+        } else {
+            *(ptr+5) = atof(line+58);
+        }
+    }
+ 
+    *(unsigned int *)&table->numRows = j;
+ 
+    return table;
+}
+*/
+
+static double lookupTaiUtcTable(const psTime *time)
+{
+    int hiIdx = 0;
+    int loIdx = 0;
+    int numRows = 0;
+    double jd = 0.0;
+    double mjd = 0.0;
+    double out = 0.0;
+    double denom = 0.0;
+    double const1 = 0.0;
+    double const2 = 0.0;
+    double const3 = 0.0;
+    static psImage* table = NULL;
+
+    if (table == NULL) {
+        table = readTaiUtcFile(TAIUTC_FILE);
+        if (table == NULL) {
+            psAbort(__func__,"Failed to read tai-utc.dat file");
+        }
+    }
+
+    // Number of rows is the number of rows of data read from the data file
+    numRows = table->numRows;
+
+    // Determine Julian and modified Julian dates used in table lookup and time delta calculation
+    jd = psTimeToJD(time);
+    mjd = psTimeToMJD(time);
+
+    // Variable in should be in MJD format
+    if(jd < table->data.F64[0][0]) {                                        // MJD time before start of table
+        return 0.0;
+    } else if(jd > table->data.F64[numRows-1][0]) {                         // MJD time after end of table
+        return table->data.F64[numRows-1][1];
+    } else {                                                                // All other times..interpolate
+        while(jd > table->data.F64[hiIdx][0]) {
+            hiIdx++;
+            if(hiIdx >= numRows) {
+                psError(__func__, " : Line %d - High index too big. Value: %d", __LINE__, hiIdx);
+                return 0.0;
+            }
+        }
+        loIdx = hiIdx--;
+        if(loIdx < 0) {
+            psError(__func__, " : Line %d - Low index too small. Value: %d", __LINE__, loIdx);
+            return 0.0;
+        }
+
+        denom = table->data.F64[hiIdx][0]-table->data.F64[loIdx][0];
+        if(fabs(denom) < FLT_EPSILON) {
+            psError(__func__, " : Line %d - Divide by zero error during interpolation", __LINE__);
+            return 0.0;
+        } else {
+
+            // Interpolate three constants required to calculate TAI-UTC
+            const1 = table->data.F64[loIdx][1]+(table->data.F64[hiIdx][1]-table->data.F64[loIdx][1])
+                     *(jd-table->data.F64[loIdx][0])/denom;
+
+            const2 = table->data.F64[loIdx][2]+(table->data.F64[hiIdx][2]-table->data.F64[loIdx][2])
+                     *(jd-table->data.F64[loIdx][0])/denom;
+
+            const3 = table->data.F64[loIdx][3]+(table->data.F64[hiIdx][3]-table->data.F64[loIdx][3])
+                     *(jd-table->data.F64[loIdx][0])/denom;
+        }
+    }
+
+    out = const1 + (mjd - const2) * const3;
+
+    return out;
+}
+
+static double lookupSer7Table(const psTime *time, int col)
+{
+    int hiIdx = 0;
+    int loIdx = 0;
+    int numRows = 0;
+    double out = 0.0;
+    double denom = 0.0;
+    double mjdUtc = 0.0;
+    static psImage* table = NULL;
+
+    if (table == NULL) {
+        table = readSer7File(SER7_FILE);
+        if (table == NULL) {
+            psAbort(__func__,"Failed to read the ser7.dat file.");
+        }
+    }
+
+    // Number of rows is the number of rows of data read from the data file
+    numRows = table->numRows;
+
+    // Interpolation value in should be in MJD format
+    mjdUtc = psTimeToMJD(time);
+    if(mjdUtc < table->data.F64[0][3]) {                                    // MJD time before start of table
+        psError(__func__, " : Line %d - MJD too small. Value: %d", __LINE__, mjdUtc);
+
+    } else if(mjdUtc > table->data.F64[numRows-1][3]) {                     // MJD time after end of table
+        psError(__func__, " : Line %d - MJD too big. Value: %d", __LINE__, mjdUtc);
+    } else {                                                                // All other times..interpolate
+        while(mjdUtc > table->data.F64[hiIdx][3]) {
+            hiIdx++;
+            if(hiIdx >= numRows) {
+                psError(__func__, " : Line %d - High index too big. Value: %d", __LINE__, hiIdx);
+                return 0.0;
+            }
+        }
+
+        loIdx = hiIdx--;
+        if(loIdx < 0) {
+            psError(__func__, " : Line %d - Low index too small. Value: %d", __LINE__, loIdx);
+        }
+
+        denom = table->data.F64[hiIdx][3] - table->data.F64[loIdx][3];
+        if(fabs(denom) < FLT_EPSILON) {
+            psError(__func__, " : Line %d - Dividie by zero error during interpolation", __LINE__);
+        } else {
+            out = table->data.F64[loIdx][col]+(table->data.F64[hiIdx][col]-table->data.F64[loIdx][col])
+                  *(mjdUtc-table->data.F64[loIdx][3])/denom;
+        }
+    }
+
+    return out;
+}
+
+psTime* psTimeGetTime(psTimeType type)
+{
+    struct timeval now;
+    psTime *time = NULL;
+
+
+    // Allocate psTime struct
+    ALLOC_TIME(time);
+
+    if (gettimeofday(&now, (struct timezone *)0) == -1) {
+        psError(__func__, " : Line %d - Failed to get time", __LINE__);
+        return NULL;
+    }
+
+    // Convert timeval time to psTime
+    time->sec = now.tv_sec;
+    time->usec = now.tv_usec;
+    time->type = type;
+
+    // Add most leapseconds to UTC time to get TAI time if necessary
+    if(type == PS_TIME_TAI) {
+        time->sec += psTimeGetTAIDelta(time);
+    }
+
+    return time;
+}
+
+psTime* psTimeConvert(psTime *time, psTimeType type)
+{
+    double delta = 0.0;
+
+
+    if(time->type == type) {
+        psError(__func__, " : Line %d - Time is already in the correct psTime format. Time type: %d", __LINE__, type);
+        return NULL;
+    }
+
+    delta = psTimeGetTAIDelta(time);
+
+    if(type == PS_TIME_UTC) {
+        time->sec = time->sec - delta;    // User wants UTC time. Remove leapseconds.
+    } else if(type == PS_TIME_TAI) {
+        time->sec = time->sec + delta;    // User wants TAI time. Add leapseconds.
+    } else {
+        psError(__func__, " : Line %d - Invalid psTimeType: %d", __LINE__, type);
+    }
+
+    return time;
+}
+
+double psTimeToLST(psTime *time, double longitude)
+{
+    psF64  jdTdtDays    =  0.0;
+    psF64  jdUt1Days    =  0.0;
+    psF64  mjdUt1Days   =  0.0;
+    psF64  lmstRad      =  0.0;
+    psF64  fracDays     =  0.0;
+    psF64  gmstRad      =  0.0;
+    psF64  t            =  0.0;
+    psF64  tu           =  0.0;
+    psF64  ut1UtcDbl    =  0.0;
+    psF64  const1       =  24110.5493771;
+    psF64  const2       =  8639877.3173760;
+    psF64  const3       =  307.4771600;
+    psF64  const4       =  0.0931118;
+    psF64  const5       = -0.0000062;
+    psF64  const6       =  0.0000013;
+    psTime *ut1UtcDelta = NULL;
+    psTime *tdtDelta    = NULL;
+    psTime *tdtTime     = NULL;
+    psTime *taiTime     = NULL;
+    psTime *utcTime     = NULL;
+    psTime *ut1Time     = NULL;
+
+
+    // Calculate TAI or UTC time based on type of time user passes
+    if(time->type == PS_TIME_TAI) {
+        taiTime = psMemIncrRefCounter(time);
+        ALLOC_TIME(utcTime);
+        utcTime->sec = taiTime->sec - psTimeGetTAIDelta(time);
+        utcTime->usec = taiTime->usec;
+        utcTime->type = PS_TIME_UTC;
+    } else if(time->type == PS_TIME_UTC) {
+        utcTime = psMemIncrRefCounter(time);
+        ALLOC_TIME(taiTime);
+        taiTime->sec = utcTime->sec + psTimeGetTAIDelta(time);
+        taiTime->usec = utcTime->usec;
+        taiTime->type = PS_TIME_TAI;
+    }
+
+    // Convert Universal Time (UTC) to  UT1
+    ALLOC_TIME(ut1UtcDelta);
+    ut1UtcDelta->type = PS_TIME_UTC;
+
+    ut1UtcDbl = psTimeGetUT1Delta(utcTime)*1e6;
+    ut1UtcDelta->usec = (psU32)fabs(ut1UtcDbl);
+    if(ut1UtcDbl<0) {
+        ut1Time = psTimeSubtract(utcTime, ut1UtcDelta);
+    } else {
+        ut1Time = psTimeAdd(utcTime, ut1UtcDelta);
+    }
+
+
+    // Calculate UT1 as Julian Centuries since J2000.0
+    jdUt1Days = psTimeToJD(ut1Time);
+    mjdUt1Days = psTimeToMJD(ut1Time);
+    t = (jdUt1Days - 2451545.0)/36525.0;
+
+    // Calculate Terrestial Dynamical Time (TDT)
+    ALLOC_TIME(tdtDelta);
+    tdtDelta->sec = 32;
+    tdtDelta->usec = 184000;
+    tdtTime = psTimeAdd(taiTime, tdtDelta);
+
+    // Calculate TDT as Julian centuries since J2000.0
+    jdTdtDays = psTimeToJD(tdtTime);
+    tu = (jdTdtDays - 2451545.0)/36525.0;
+
+    // Calculate fractional part of MJD
+    fracDays = fmod(mjdUt1Days, 1.0);
+
+    // Calculate Greenwich Mean Sidereal Time (GMST) in radians. Equation set up to minimize multiplications
+    gmstRad = fracDays*TWOPI+(const1+const2*tu+t*(const3+t*(const4+t*(const5+const6*t))))*S2R;
+
+    // Place GMST between 0 and 2*pi
+    gmstRad = fmod(gmstRad, TWOPI);
+
+    // Calculate Local Mean Sidereal Time (LMST) in radians
+    lmstRad = gmstRad + longitude;
+
+    // Free temporary structs
+    psFree(ut1UtcDelta);
+    psFree(ut1Time);
+    psFree(tdtTime);
+    psFree(tdtDelta);
+    psFree(utcTime);
+    psFree(taiTime);
+
+    return lmstRad;
+}
+
+double psTimeGetUT1Delta(const psTime *time)
+{
+    return lookupSer7Table(time, 6);
+}
+
+struct psSphere* psTimeGetPoleCoords(const psTime* time)
+{
+
+    double x = lookupSer7Table((psTime*)time, 4);
+    double y = lookupSer7Table((psTime*)time, 5);
+
+    struct psSphere* output = psAlloc(sizeof(psSphere));
+    output->r = x * M_PI / 648000.0; // x in arcsec converted to radians, i.e., x/60/60*M_PI/180
+    output->d = y * M_PI / 648000.0;
+
+    return output;
+}
+
+double psTimeGetTAIDelta(const psTime *time)
+{
+    return lookupTaiUtcTable(time);
+}
+
+long psTimeLeapseconds(const psTime *time1, const psTime *time2)
+{
+    long diff = 0;
+
+    // NULL error checks
+    CHECK_NULL_TIME(time1,0);
+    CHECK_NULL_TIME(time2,0);
+
+    diff = abs(psTimeGetTAIDelta((psTime*)time1)-psTimeGetTAIDelta((psTime*)time2));
+
+    return diff;
+}
+
+double psTimeToJD(const psTime *time)
+{
+    double jd = 0.0;
+
+
+    // NULL error check
+    CHECK_NULL_TIME(time,0.0);
+
+    // Julian date conversion
+    if(time->sec < 0) {
+        jd = time->sec / SEC_PER_DAY - time->usec / USEC_PER_DAY + 2440587.5; // psTime earlier than epoch
+    } else {
+        jd = time->sec / SEC_PER_DAY + time->usec / USEC_PER_DAY + 2440587.5; // psTime greater than epoch
+    }
+
+    return jd;
+}
+
+double psTimeToMJD(const psTime *time)
+{
+    double mjd = 0.0;
+
+
+    // NULL error check
+    CHECK_NULL_TIME(time,0.0);
+
+    // Modified Julian date conversion
+    if(time->sec < 0) {
+        mjd = time->sec / SEC_PER_DAY - time->usec / USEC_PER_DAY + 40587.0; // psTime earlier than epoch
+    } else {
+        mjd = time->sec / SEC_PER_DAY + time->usec / USEC_PER_DAY + 40587.0; // psTime greater than epoch
+    }
+
+    return mjd;
+}
+
+char* psTimeToISOTime(const psTime *time)
+{
+    int ms = 0;
+    char *timeString = NULL;
+    char *tempString = NULL;
+    struct tm *tmTime = NULL;
+    time_t sec;
+
+
+    // NULL error check
+    CHECK_NULL_TIME(time,NULL);
+
+    tempString = psAlloc(MAX_TIME_STRING_LENGTH);
+    timeString = psAlloc(MAX_TIME_STRING_LENGTH);
+
+    ms = time->usec / 1000;
+    sec = time->sec;
+
+    // tmTime variable is statically allocated, no need to free
+    tmTime = gmtime(&sec);
+
+    // Converts psTime to YYYY-MM-DDThh:mm:ss.sss in string form
+    if (!strftime(tempString, MAX_TIME_STRING_LENGTH, "%Y-%m-%dT%H:%M:%S", tmTime)) {
+        psError(__func__, " : Line %d - Failed strftime conversion", __LINE__);
+    }
+
+    if (snprintf(timeString, MAX_TIME_STRING_LENGTH, "%s.%3.3dZ", tempString, ms) < 0) {
+        psError(__func__, " : Line %d - Failed snprintf conversion", __LINE__);
+    }
+    psFree(tempString);
+
+    return timeString;
+}
+
+struct timeval psTimeToTimeval(const psTime *time)
+{
+    struct timeval timevalTime;
+
+
+    // NULL error check
+    CHECK_NULL_TIME(time,timevalTime);
+
+    timevalTime.tv_sec = time->sec;
+    timevalTime.tv_usec = time->usec;
+
+    return timevalTime;
+}
+
+struct tm* psTimeToTM(const psTime *time)
+{
+    long cent = 0;
+    long year = 0;
+    long month = 0;
+    long day = 0;
+    long hour = 0;
+    long minute = 0;
+    long seconds = 0;
+    long temp = 0;
+    struct tm* tmTime = NULL;
+
+
+    seconds = time->sec%60;
+    minute = time->sec/60%60;
+    hour = time->sec/3600%24;
+    day = (time->sec+62135596800)/86400;
+
+    // Add 306 days to make relative to Mar 1, 0; also adjust day to be within a range (1..2**28-1) where our
+    // calculations will work with 32bit ints
+    if(day > (pow(2, 28)-307))
+    {
+        temp = (day - 146097+306)/146097+1;         // Avoid overflow if day close to maxint
+        day -= temp * 146097-306;
+    } else if((day += 306 ) <= 0)
+    {
+        temp = -( -day / 146097 + 1);               // Avoid ambiguity in C division of negatives
+        day -= temp * 146097;
+    }
+
+    cent = (day*4-1)/146097;                        // Calc number of centuries day is after 29 Feb of yr 0
+    day -= cent*146097/4;                           // 4 centuries = 146097 days
+    year = (day*4-1)/1461;                          // Calc number of years into the century
+    day -= year*1461/4;                             // Again March-based (4 yrs =\u02dc 146[01] days)
+    month = (day*12+1093)/367;                      // Get the month (3..14 represent March through
+    day -= (month*367-1094)/12;                     // February of following year)
+    year += cent*100+temp*400;                      // Get the real year, which is off by
+
+    // One if month is January or February
+    if(month > 12)
+    {
+        year++;
+        month -= 12;
+    }
+
+    // Allocate output
+    tmTime = (struct tm*)psAlloc(sizeof(struct tm));
+    if (tmTime == NULL)
+    {
+        psAbort(__func__, " : Line %d - Failed to allocate memory", __LINE__);
+    }
+
+    tmTime->tm_year = year - 1900;
+    tmTime->tm_mon = month - 1;
+    tmTime->tm_mday = day + 1;
+    tmTime->tm_hour = hour;
+    tmTime->tm_min = minute;
+    tmTime->tm_sec = seconds;
+    tmTime->tm_isdst = -1;
+
+    return tmTime;
+}
+
+psTime* psTimeFromJD(double time)
+{
+    double days = 0.0;
+    double seconds = 0.0;
+    psTime *outTime = NULL;
+
+
+    // Allocate psTime struct
+    ALLOC_TIME(outTime);
+
+    // Julian date conversion courtesy of Eugene Magnier
+    days = time - 2440587.5;
+    seconds = days * SEC_PER_DAY;
+    if(seconds < 0.0) {
+        outTime->usec = (seconds - (long)seconds) * -1000000.0;  // psTime earlier than epoch
+    } else {
+        outTime->usec = (seconds - (long)seconds) * 1000000.0;   // psTime greater than epoch
+    }
+    outTime->sec = seconds;
+
+    return outTime;
+}
+
+psTime* psTimeFromMJD(double time)
+{
+    double days = 0.0;
+    double seconds = 0.0;
+    psTime *outTime = NULL;
+
+
+    // Allocate psTime struct
+    ALLOC_TIME(outTime);
+
+    // Modified Julian date conversion courtesy of Eugene Magnier
+    days = time - 40587.0;
+    seconds = days * SEC_PER_DAY;
+    if(seconds < 0.0) {
+        outTime->usec = (seconds - (long)seconds) * -1000000.0;  // psTime earlier than epoch
+    } else {
+        outTime->usec = (seconds - (long)seconds) * 1000000.0;   // psTime greater than epoch
+    }
+    outTime->sec = seconds;
+
+    return outTime;
+}
+
+psTime* psTimeFromISOTime(const char *time)
+{
+    char tempString[MAX_TIME_STRING_LENGTH];
+    int month;
+    int day;
+    int year;
+    int hour;
+    int minute;
+    int second;
+    int millisecond;
+    struct tm tmTime;
+    psTime *outTime = NULL;
+
+
+    // Preserve input string by creating duplicate
+    strncpy(tempString, time, MAX_TIME_STRING_LENGTH);
+
+    // Convert YYYY-MM-DDThh:mm:ss.sss in string form to tm time
+    year = atoi(strtok(tempString, "-"));
+    if (year < 0) {
+        psError(__func__, "Years less than 0 not allowed. Value: %d", year);
+        return outTime;
+    }
+
+    month = atoi(strtok(NULL, "-"));
+    if (month < 1 || month > 12) {
+        psError(__func__, "Month must have a value from 1 to 12. Value: %d", month);
+        return outTime;
+    }
+
+    day = atoi(strtok(NULL, "T"));
+    if (day < 1 || day > 31) {
+        psError(__func__, "Day must have a value from 1 to 31. Value: %d", day);
+        return outTime;
+    }
+
+    hour = atoi(strtok(NULL, ":"));
+    if (hour < 0 || hour > 23) {
+        psError(__func__, "Hour must have a value from 0 to 23. Value: %d", hour);
+        return outTime;
+    }
+
+    minute = atoi(strtok(NULL, ":"));
+    if (minute < 0 || minute > 59) {
+        psError(__func__, "Minute must have a value from 0 to 59. Value: %d", minute);
+        return outTime;
+    }
+
+    second = atoi(strtok(NULL, "."));
+    if (second < 0 || second > 59) {
+        psError(__func__, "Second must have a value from 0 to 59. Value: %d", second);
+        return outTime;
+    }
+
+    millisecond = atoi(strtok(NULL, "Z"));
+    if (millisecond < 0 || millisecond > 1000) {
+        psError(__func__, "Millisecond must have a value from 0 to 999. Value: %d", millisecond);
+        return outTime;
+    }
+
+    tmTime.tm_year = year - 1900;
+    tmTime.tm_mon = month - 1;
+    tmTime.tm_mday = day;
+    tmTime.tm_hour = hour;
+    tmTime.tm_min = minute;
+    tmTime.tm_sec = second;
+    tmTime.tm_isdst = -1;
+
+    // Convert tm time to psTime
+    outTime = psTimeFromTM(&tmTime);
+    outTime->usec = millisecond * 1000;
+
+    return outTime;
+}
+
+psTime* psTimeFromTimeval(const struct timeval *time)
+{
+    psTime *outTime = NULL;
+
+
+    // NULL error check
+    CHECK_NULL_TIME(time,NULL);
+
+    // Allocate psTime struct
+    ALLOC_TIME(outTime)
+
+    // Convert to psTime
+    outTime->sec = time->tv_sec;
+    outTime->usec = time->tv_usec;
+
+    return outTime;
+}
+
+psTime* psTimeFromTM(const struct tm* time)
+{
+    long year;
+    long month;
+    long day;
+    long hour;
+    long minute;
+    long seconds;
+    long temp;
+    psTime *outTime = NULL;
+
+    // NULL error check
+    CHECK_NULL_TIME(time,NULL);
+
+    // Allocate psTime struct
+    ALLOC_TIME(outTime);
+
+    // Extract data from TM struct
+    year = time->tm_year + 1900;
+    month = time->tm_mon + 1;
+    day = time->tm_mday;
+    hour = time->tm_hour;
+    minute = time->tm_min;
+    seconds = time->tm_sec;
+
+    // Make month in range 3..14 (treat Jan & Feb as months 13..14 of prev year)
+    if( month <= 2 )
+    {
+        year -= (temp = (14 - month) / 12);
+        month += 12 * temp;
+    } else if(month > 14)
+    {
+        year += (temp = (month - 3) / 12);
+        month -= 12 * temp;
+    }
+
+    // Make year positive
+    if (year < 0 )
+    {
+        day -= 146097 * (temp = (399 - year) / 400);
+        year += 400 * temp;
+    }
+
+    // Add day of month, days of previous 0-11 month period that began w/March, days of previous 0-399 year
+    // period that began w/March of a 400-multiple year), days of any 400-year periods before that, and 306
+    // days to adjust from Mar 1, year 0-relative to Jan 1, year 1-relative. Add hours, minutes, and seconds.
+    day += (month * 367 - 1094) / 12 + year % 100 * 1461 / 4 + (year/100 * 36524 + year/400) - 306;
+    outTime->sec = (((day - 1) * SEC_PER_DAY) - 62135596800) + hour*SEC_PER_HOUR + minute*SEC_PER_MINUTE + seconds;
+
+    // C's TM does not define a microsecond field. Microseconds must be manipulated by calling function.
+    outTime->usec = 0;
+
+    return outTime;
+}
+
+psTime* psTimeAdd(const psTime *tai1, const psTime *tai2)
+{
+    long deltaUsec = 0;
+    psTime *outTime = NULL;
+
+
+    if(tai1->type != tai2->type) {
+        psError(__func__, " : Line %d - Argument types inconsistent for time addition", __LINE__);
+        return NULL;
+    }
+
+    ALLOC_TIME(outTime);
+    outTime->type = tai1->type;
+    outTime->sec = tai1->sec + tai2->sec;
+    deltaUsec = tai1->usec + tai2->usec;
+
+    // Adjust time in case of microsecond overflow after subtraction
+    if(deltaUsec > 1e6) {
+        outTime->sec++;
+        outTime->usec = 2e6 - deltaUsec;
+    } else {
+        outTime->usec = deltaUsec;
+    }
+
+    return outTime;
+}
+
+psTime* psTimeSubtract(const psTime *tai1, const psTime *tai2)
+{
+    long deltaUsec = 0;
+    psTime *outTime = NULL;
+
+
+    if(tai1->type != tai2->type) {
+        psError(__func__, " : Line %d - Argument types inconsistent for time subtraction", __LINE__);
+        return NULL;
+    }
+
+    ALLOC_TIME(outTime);
+    outTime->type = tai1->type;
+    outTime->sec = tai1->sec - tai2->sec;
+    deltaUsec = (long)tai1->usec - (long)tai2->usec;
+
+    // Adjust time in case of microsecond underflow after subtraction
+    if(deltaUsec < 0) {
+        outTime->sec--;
+        outTime->usec = 1e6+deltaUsec;
+    } else {
+        outTime->usec = deltaUsec;
+    }
+
+    return outTime;
+}
+
+psTime* psTimeDelta(const psTime *tai1, const psTime *tai2)
+{
+    long deltaUsec = 0;
+    psTime *outTime = NULL;
+
+
+    if(tai1->type != tai2->type) {
+        psError(__func__, " : Line %d - Argument types inconsistent for time subtraction", __LINE__);
+        return NULL;
+    }
+
+    ALLOC_TIME(outTime);
+    outTime->type = tai1->type;
+    outTime->sec = tai1->sec - tai2->sec;
+    deltaUsec = tai1->usec - tai2->usec;
+
+    // Adjust time in case of microsecond underflow after subtraction
+    if(deltaUsec < 0) {
+        outTime->sec--;
+        outTime->usec = 1e6+deltaUsec;
+    } else {
+        outTime->usec = deltaUsec;
+    }
+
+    outTime->sec = abs(outTime->sec);
+
+    return outTime;
+}
Index: /branches/rel3/psLib/src/astronomy/psTime.h
===================================================================
--- /branches/rel3/psLib/src/astronomy/psTime.h	(revision 2163)
+++ /branches/rel3/psLib/src/astronomy/psTime.h	(revision 2163)
@@ -0,0 +1,315 @@
+/** @file  psTime.h
+ *
+ *  @brief Definitions for time, time utilities, and conversion functions for use with psLib astronomy
+ *  functions.
+ *
+ *  A collection of functions are required by psLib to manipulate time data. These functions primarily consist
+ *  of conversions between specific time formats.  PSLib currently uses the UNIX timeval time system as the
+ *  base upon which International Atomic Time (TAI) and Universal Time Coordinated (UTC) are calculated. TAI
+ *  time varies over time due to the earth's rotation and the movement of the continental plates. It is
+ *  currentls 32 seconds faster than UTC/timeval time. The conversion between TAI and UTC time for other dates
+ *  is given in the table below, which comes from:
+ *
+ *  ftp://maia.usno.navy.mil/ser7/tai-utc.dat
+ *
+ *  This table is placed into a static array and used by the psTime functions for conversions.
+ *
+ *   1961 JAN  1 =JD 2437300.5  TAI-UTC=   1.4228180 S + (MJD - 37300.) X 0.001296 S
+ *   1961 AUG  1 =JD 2437512.5  TAI-UTC=   1.3728180 S + (MJD - 37300.) X 0.001296 S
+ *   1962 JAN  1 =JD 2437665.5  TAI-UTC=   1.8458580 S + (MJD - 37665.) X 0.0011232S
+ *   1963 NOV  1 =JD 2438334.5  TAI-UTC=   1.9458580 S + (MJD - 37665.) X 0.0011232S
+ *   1964 JAN  1 =JD 2438395.5  TAI-UTC=   3.2401300 S + (MJD - 38761.) X 0.001296 S
+ *   1964 APR  1 =JD 2438486.5  TAI-UTC=   3.3401300 S + (MJD - 38761.) X 0.001296 S
+ *   1964 SEP  1 =JD 2438639.5  TAI-UTC=   3.4401300 S + (MJD - 38761.) X 0.001296 S
+ *   1965 JAN  1 =JD 2438761.5  TAI-UTC=   3.5401300 S + (MJD - 38761.) X 0.001296 S
+ *   1965 MAR  1 =JD 2438820.5  TAI-UTC=   3.6401300 S + (MJD - 38761.) X 0.001296 S
+ *   1965 JUL  1 =JD 2438942.5  TAI-UTC=   3.7401300 S + (MJD - 38761.) X 0.001296 S
+ *   1965 SEP  1 =JD 2439004.5  TAI-UTC=   3.8401300 S + (MJD - 38761.) X 0.001296 S
+ *   1966 JAN  1 =JD 2439126.5  TAI-UTC=   4.3131700 S + (MJD - 39126.) X 0.002592 S
+ *   1968 FEB  1 =JD 2439887.5  TAI-UTC=   4.2131700 S + (MJD - 39126.) X 0.002592 S
+ *   1972 JAN  1 =JD 2441317.5  TAI-UTC=  10.0       S + (MJD - 41317.) X 0.0      S
+ *   1972 JUL  1 =JD 2441499.5  TAI-UTC=  11.0       S + (MJD - 41317.) X 0.0      S
+ *   1973 JAN  1 =JD 2441683.5  TAI-UTC=  12.0       S + (MJD - 41317.) X 0.0      S
+ *   1974 JAN  1 =JD 2442048.5  TAI-UTC=  13.0       S + (MJD - 41317.) X 0.0      S
+ *   1975 JAN  1 =JD 2442413.5  TAI-UTC=  14.0       S + (MJD - 41317.) X 0.0      S
+ *   1976 JAN  1 =JD 2442778.5  TAI-UTC=  15.0       S + (MJD - 41317.) X 0.0      S
+ *   1977 JAN  1 =JD 2443144.5  TAI-UTC=  16.0       S + (MJD - 41317.) X 0.0      S
+ *   1978 JAN  1 =JD 2443509.5  TAI-UTC=  17.0       S + (MJD - 41317.) X 0.0      S
+ *   1979 JAN  1 =JD 2443874.5  TAI-UTC=  18.0       S + (MJD - 41317.) X 0.0      S
+ *   1980 JAN  1 =JD 2444239.5  TAI-UTC=  19.0       S + (MJD - 41317.) X 0.0      S
+ *   1981 JUL  1 =JD 2444786.5  TAI-UTC=  20.0       S + (MJD - 41317.) X 0.0      S
+ *   1982 JUL  1 =JD 2445151.5  TAI-UTC=  21.0       S + (MJD - 41317.) X 0.0      S
+ *   1983 JUL  1 =JD 2445516.5  TAI-UTC=  22.0       S + (MJD - 41317.) X 0.0      S
+ *   1985 JUL  1 =JD 2446247.5  TAI-UTC=  23.0       S + (MJD - 41317.) X 0.0      S
+ *   1988 JAN  1 =JD 2447161.5  TAI-UTC=  24.0       S + (MJD - 41317.) X 0.0      S
+ *   1990 JAN  1 =JD 2447892.5  TAI-UTC=  25.0       S + (MJD - 41317.) X 0.0      S
+ *   1991 JAN  1 =JD 2448257.5  TAI-UTC=  26.0       S + (MJD - 41317.) X 0.0      S
+ *   1992 JUL  1 =JD 2448804.5  TAI-UTC=  27.0       S + (MJD - 41317.) X 0.0      S
+ *   1993 JUL  1 =JD 2449169.5  TAI-UTC=  28.0       S + (MJD - 41317.) X 0.0      S
+ *   1994 JUL  1 =JD 2449534.5  TAI-UTC=  29.0       S + (MJD - 41317.) X 0.0      S
+ *   1996 JAN  1 =JD 2450083.5  TAI-UTC=  30.0       S + (MJD - 41317.) X 0.0      S
+ *   1997 JUL  1 =JD 2450630.5  TAI-UTC=  31.0       S + (MJD - 41317.) X 0.0      S
+ *   1999 JAN  1 =JD 2451179.5  TAI-UTC=  32.0       S + (MJD - 41317.) X 0.0      S
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-12 01:34:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PSTIME_H
+#define PSTIME_H
+
+#include <time.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include "psType.h"
+#include "psImage.h"
+
+struct psSphere;
+
+/// @addtogroup Time
+/// @{
+
+
+/** Time type.
+ *
+ * Enumeration for psTime types, TAI or UTC time.
+ */
+typedef enum {
+    PS_TIME_TAI,        ///< Temps Atomique International (TAI) time (time with leapseconds).
+    PS_TIME_UTC,        ///< Universal Time Coordinated (UTC) time (time without leapseconds).
+} psTimeType;
+
+/** Definition of psTime.
+ *
+ *  The psTime struct is used by psLib to represent time values critical to
+ *  astronomical calculations.  This structure represents a time which is
+ *  equivalent to TAI (International Atomic Time) and is measured in both
+ *  seconds and microseconds.
+ */
+typedef struct psTime
+{
+    psS64 sec;                          ///< Seconds since epoch, Jan 1, 1970.
+    psU32 usec;                         ///< Microseconds since last second.
+    psTimeType type;                    ///< Type of time.
+}
+psTime;
+
+/** Get current time.
+ *
+ * Gets current time from the system clock. User must specify the psTimeType (PS_TIME_TAI or PS_TIME_UTC) in
+ * the argument.
+ *
+ *  @return  psTime*: Struct with current time.
+ */
+psTime* psTimeGetTime(
+    psTimeType type                     ///< Type of time to get (UTC or TAI).
+);
+
+/** Convert psTime to UTC or TAI time.
+ *
+ *  Converts psTime to UTC or TAI time based on the psTimeType argument.
+ *
+ *  @return  psTime*: Pointer to psTime.
+ */
+psTime* psTimeConvert(
+    psTime *time,                       ///< Time to be converted.
+    psTimeType type                     ///< Type to be converted to.
+);
+
+/** Convert psTime to Local Mean Sidereal Time (LST).
+ *
+ *  Converts psTime at the given longitude to LST time. If the input time is not in UTC format, then it is
+ *  converted.
+ *
+ *  @return  double: LST Time.
+ */
+double psTimeToLST(
+    psTime *time,                       ///< psTime to be converted.
+    double longitude                    ///< Longitude.
+);
+
+/** Determine UT1 - UTC from table lookup.
+ *
+ *  This function is necessary to for various SLALIB functions.
+ *
+ *  @return  double: Time difference.
+ */
+double psTimeGetUT1Delta(
+    const psTime *time                  ///< psTime to be looked up.
+);
+
+/** Determine TAI - UTC from table lookup.
+ *
+ *  This function is necessary to for various psTime functions.
+ *
+ *  @return  double: Time difference.
+ */
+double psTimeGetTAIDelta(
+    const psTime *time                  ///< psTime to be looked up.
+);
+
+/** Determine polar coordinates at a given time.
+ *
+ *  Determines the orientation of the polar axis at the given time.
+ *
+ *  @return  psSphere*: Spherical coordinates of Earth's polar axias.
+ */
+struct psSphere* psTimeGetPoleCoords(
+                const psTime *time                  ///< psTime determine polar orientation.
+            );
+
+/** Calculate the number of leapseconds between two times.
+ *
+ *  Calculates the number of leapseconds between two times.
+ *
+ *  @return  long: leapseconds added between given times
+ */
+long psTimeLeapseconds(
+    const psTime* time1,                ///< First input time.
+    const psTime* time2                 ///< Second input time.
+);
+
+/** Convert psTime to Julian date time.
+ *
+ *  Converts psTime to Julian date (JD) time. This function does not add or subtract leapseconds.
+ *
+ *  @return  double: Julian Date (JD) time.
+ */
+double psTimeToJD(
+    const psTime* time                  ///< Input time to be converted.
+);
+/** Convert psTime to modified Julian date time.
+ *
+ *  Converts psTime to modified Julian date (MJD) time. This function does not add or subtract leapseconds.
+ *
+ *  @return  double: Modified Julian Days (MJD) time.
+ */
+double psTimeToMJD(
+    const psTime* time                  ///< Input time to be converted.
+);
+
+/** Convert psTime to ISO8601 formatted string.
+ *
+ *  Converts psTime to a null terminated string in the form of YYYY-MM-DDThh:mm:ss.sss. This function does not
+ *  add or subtract leapseconds.
+ *
+ *  @return  char*: Pointer null terminated array of chars in ISO time.
+ */
+char* psTimeToISOTime(
+    const psTime* time                  ///< Input time to be converted.
+);
+
+/** Convert psTime to timeval time.
+ *
+ *  Converts psTime to timeval time. This function does not add or subtract leapseconds.
+ *
+ *  @return  timeval: timeval struct time.
+ */
+struct timeval psTimeToTimeval(
+                const psTime* time                  ///< Input time to be converted.
+            );
+
+/** Convert psTime to tm time.
+ *
+ * Converts psTime to tm time. This function is based on a Perl algorithm availble in the Pan-STARRS Image
+ * processing Algorithm Design Description (ADD). This function does not add or subtract leapseconds.
+ *
+ *  @return  tm: tm struct time.
+ */
+struct tm* psTimeToTM(
+                const psTime *time                  ///< Input time to be converted.
+            );
+
+/** Convert JD to psTime.
+ *
+ *  Converts JD time to psTime. This function does not add or subtract leapseconds.
+ *
+ *  @return  psTime: time.
+ */
+psTime* psTimeFromJD(
+    double time                         ///< Input time to be converted.
+);
+
+/** Convert MJD to psTime.
+ *
+ *  Converts MJD time to psTime. This function does not add or subtract leapseconds.
+ *
+ *  @return  psTime: time.
+ */
+psTime* psTimeFromMJD(
+    double time                         ///< Input time to be converted.
+);
+
+/** Convert ISO to psTime.
+ *
+ *  Converts ISO time to psTime. This function does not add or subtract leapseconds.
+ *
+ *  @return  psTime*: time
+ */
+psTime* psTimeFromISOTime(
+    const char* time                    ///< Input time to be converted.
+);
+
+/** Convert timeval to psTime.
+ *
+ *  Converts timeval time to psTime. This function does not add or subtract leapseconds.
+ *
+ *  @return  psTime*: time.
+ */
+psTime* psTimeFromTimeval(
+    const struct timeval *time          ///< Input time to be converted.
+);
+
+/** Convert tm time to psTime.
+ *
+ *  Converts tm time to psTime. This function is based on a Perl algorithm availble in the Pan-STARRS Image
+ * processing Algorithm Design Description (ADD). This function does not add or subtract leapseconds.
+ *
+ *  @return  psTime*: time.
+ */
+psTime* psTimeFromTM(
+    const struct tm *time               ///< Input time to be converted.
+);
+
+/** Add two TAI times.
+ *
+ *  Adds two TAI times. This function does not add or subtract leapseconds.
+ *
+ *  @return  psTime*: time.
+ */
+psTime* psTimeAdd(
+    const psTime *tai1,                 ///< First TAI time.
+    const psTime *tai2                  ///< Second TAI time.
+);
+
+/** Subtract two TAI times.
+ *
+ *  Subtracts two TAI times. This function does not add or subtract leapseconds.
+ *
+ *  @return  psTime*: time.
+ */
+psTime* psTimeSubtract(
+    const psTime *tai1,                 ///< First TAI time.
+    const psTime *tai2                  ///< Second TAI time.
+);
+
+
+/** Find delta of two TAI times.
+ *
+ *  Finds the absolute difference of two TAI times. This function does not add or subtract leapseconds.
+ *
+ *  @return  psTime*: time.
+ */
+psTime* psTimeDelta(
+    const psTime *tai1,                 ///< First TAI time.
+    const psTime *tai2                  ///< Second TAI time.
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/astronomy/slalib.h
===================================================================
--- /branches/rel3/psLib/src/astronomy/slalib.h	(revision 2163)
+++ /branches/rel3/psLib/src/astronomy/slalib.h	(revision 2163)
@@ -0,0 +1,201 @@
+/** @file  slalib.h
+*
+*  @brief Simple wrapper of the required fortran SLALIB functions
+*
+*  @ingroup AstroImage
+*
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-12 21:10:41 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#ifndef SLALIB_H
+#define SLALIB_H
+
+#ifdef FORTRAN_UNDERSCORE_PREFIX
+#ifdef FORTRAN_DOUBLE_UNDERSCORE_SUFFIX
+#ifdef FORTRAN_UPPERCASE
+#define fslaAoppa _SLA_AOPPA__
+#define fslaAopqk _SLA_AOPQK__
+#define fslaOapqk _SLA_OAPQK__
+#define fslaAirmas _SLA_AIRMAS__
+#else
+#define fslaAoppa _sla_aoppa__
+#define fslaAopqk _sla_aopqk__
+#define fslaOapqk _sla_oapqk__
+#define fslaAirmas _sla_airmas__
+#endif
+#elif FORTRAN_NO_UNDERSCORE_SUFFIX
+#ifdef FORTRAN_UPPERCASE
+#define fslaAoppa _SLA_AOPPA
+#define fslaAopqk _SLA_AOPQK
+#define fslaOapqk _SLA_OAPQK
+#define fslaAirmas _SLA_AIRMAS
+#else
+#define fslaAoppa _sla_aoppa
+#define fslaAopqk _sla_aopqk
+#define fslaOapqk _sla_oapqk
+#define fslaAirmas _sla_airmas
+#endif
+#else
+#ifdef FORTRAN_UPPERCASE
+#define fslaAoppa _SLA_AOPPA_
+#define fslaAopqk _SLA_AOPQK_
+#define fslaOapqk _SLA_OAPQK_
+#define fslaAirmas _SLA_AIRMAS_
+#else
+#define fslaAoppa _sla_aoppa_
+#define fslaAopqk _sla_aopqk_
+#define fslaOapqk _sla_oapqk_
+#define fslaAirmas _sla_airmas_
+#endif
+#endif
+#else
+#ifdef FORTRAN_DOUBLE_UNDERSCORE_SUFFIX
+#ifdef FORTRAN_UPPERCASE
+#define fslaAoppa SLA_AOPPA__
+#define fslaAopqk SLA_AOPQK__
+#define fslaOapqk SLA_OAPQK__
+#define fslaAirmas SLA_AIRMAS__
+#else
+#define fslaAoppa sla_aoppa__
+#define fslaAopqk sla_aopqk__
+#define fslaOapqk sla_oapqk__
+#define fslaAirmas sla_airmas__
+#endif
+#elif FORTRAN_NO_UNDERSCORE_SUFFIX
+#ifdef FORTRAN_UPPERCASE
+#define fslaAoppa SLA_AOPPA
+#define fslaAopqk SLA_AOPQK
+#define fslaOapqk SLA_OAPQK
+#define fslaAirmas SLA_AIRMAS
+#else
+#define fslaAoppa sla_aoppa
+#define fslaAopqk sla_aopqk
+#define fslaOapqk sla_oapqk
+#define fslaAirmas sla_airmas
+#endif
+#else
+#ifdef FORTRAN_UPPERCASE
+#define fslaAoppa SLA_AOPPA_
+#define fslaAopqk SLA_AOPQK_
+#define fslaOapqk SLA_OAPQK_
+#define fslaAirmas SLA_AIRMAS_
+#else
+#define fslaAoppa sla_aoppa_
+#define fslaAopqk sla_aopqk_
+#define fslaOapqk sla_oapqk_
+#define fslaAirmas sla_airmas_
+#endif
+#endif
+#endif
+
+extern void fslaAoppa(
+        const double* date,
+        const double* dut,
+        const double* elongm,
+        const double* phim,
+        const double* him,
+        const double* xp,
+        const double* yp,
+        const double* tdk,
+        const double* pmb,
+        const double* rh,
+        const double* wl,
+        const double* tlr,
+        double* AOPRMS
+    );
+
+extern void fslaAopqk(
+        const double* RAP,
+        const double* DAP,
+        double* AOPRMS,
+        double* AOB,
+        double* ZOB,
+        double* HOB,
+        double* DOB,
+        double* ROB
+    );
+
+extern void fslaOapqk(
+        char* TYPE,
+        const double* OB1,
+        const double* OB2,
+        double* AOPRMS,
+        double* RAP,
+        double* DAP
+    );
+
+extern double fslaAirmas(
+        const double* zenithDistance
+    );
+
+/*
+    void slaAoppa(date, dut, elongm, phim, hm, xp, yp, tdk, pmb, rh, wl, tlr, aoprms)
+    
+    PARAMETERS
+    
+    double date
+    double dut
+    double elongm
+    double phim
+    double hm
+    double xp
+    double yp
+    double tdk
+    double pmb
+    double rh
+    double wl
+    double tlr
+    double *aoprms
+*/
+#define slaAoppa(date,dut,elongm,phim,him,xp,yp,tdk,pmb,rh,wl,tlr,AOPRMS) \
+fslaAoppa(&date,&dut,&elongm,&phim,&him,&xp,&yp,&tdk,&pmb,&rh,&wl,&tlr,AOPRMS)
+
+/*
+    void slaAopqk(rap, dap, aoprms, aob, zob, hob, dob, rob)
+    
+    PARAMETERS
+    
+    double rap
+    double dap
+    double *aoprms
+    double *aob
+    double *zob
+    double *hob
+    double *dob
+    double *rob
+*/
+
+#define slaAopqk(RAP,DAP,AOPRMS,AOB,ZOB,HOB,DOB,ROB) \
+fslaAopqk(&RAP,&DAP,AOPRMS,AOB,ZOB,HOB,DOB,ROB)
+
+/*
+    void slaOapqk(type, ob1, ob2, aoprms, rap, dap)
+    
+    PARAMETERS
+    
+    char *type
+    double ob1
+    double ob2
+    double *aoprms
+    double *rap
+    double *dap
+*/
+
+#define slaOapqk(TYPE, OB1, OB2, AOPRMS, RAP, DAP) \
+fslaOapqk(TYPE, &OB1, &OB2, AOPRMS, RAP, DAP)
+
+/*
+    double slaAirmas(zd)
+    
+    PARAMETERS
+    
+    double zd
+*/
+#define slaAirmas(ZD) fslaAirmas(&ZD)
+
+#endif
Index: /branches/rel3/psLib/src/collections/.cvsignore
===================================================================
--- /branches/rel3/psLib/src/collections/.cvsignore	(revision 2163)
+++ /branches/rel3/psLib/src/collections/.cvsignore	(revision 2163)
@@ -0,0 +1,1 @@
+*.i
Index: /branches/rel3/psLib/src/collections/Makefile
===================================================================
--- /branches/rel3/psLib/src/collections/Makefile	(revision 2163)
+++ /branches/rel3/psLib/src/collections/Makefile	(revision 2163)
@@ -0,0 +1,92 @@
+###############################################################################
+##
+##  Makefile:   collections
+##
+##  $Revision: 1.31 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-09-11 00:43:54 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+###############################################################################
+
+# Define variable prefix to the top level project - psLib
+# This is necessary for definition is Makefile.Globals uses prefix
+
+ifndef prefix
+    export prefix=$(shell cd ../..;pwd)
+endif
+
+# Define the two targets to be built
+
+TARGET_STATIC  = libpslib.a
+
+# Include the make global definitions for the project
+
+include ../Makefile.Globals
+
+# Set CFLAGS used by the implicit rule to compile .c
+
+CFLAGS := $(CFLAGS_RELOC) -I../sysUtils -I..
+
+# Define the source objects
+ 
+SRC_OBJS = psBitSet.o \
+           psVector.o \
+           psList.o \
+           psScalar.o \
+           psCompare.o \
+           psArray.o \
+           psHash.o
+
+OBJS = $(addprefix makedir/,$(SRC_OBJS))
+
+HEADERS = $(SRC_OBJS:.o=.h)
+
+
+# Define PHONY target "all" which will make all the necessary items
+
+all: $(TARGET_STATIC)
+
+psCollectionsErrors.h: psCollectionsErrors.dat
+	perl ../parseErrorCodes.pl --data=$? $@
+
+# Rule to make static library
+
+libpslib.a: $(OBJS)
+# The ar option -r is to add/replace object and -s is to create
+# a symbol table in the archive
+	$(AR) rcs ../$@ $(OBJS)
+
+# Define PHONY target "install" which will install necessary files
+
+install: $(TARGET_STATIC)
+	install $(HEADERS) $(includedir)
+
+# Define PHONY target "distclean" which will cleanup the distribution
+
+distclean:	clean
+	$(RM) ../$(TARGET_STATIC)
+
+# Define PHONY target "clean" which will cleanup the development area
+
+clean:
+	@echo "    Deleting intermediate files for 'collections'"
+	$(RM) $(OBJS) *.lint $(SRC_OBJS:.o=.i)
+
+cleandep:
+	$(RM) $(OBJS:.o=.d)
+
+%.lint: %.c
+	splint +posixlib -exportlocal -realcompare $(INCLUDE_GLOBAL) $? > $@; cat $@
+
+%.i: %.c
+	$(CC) -E $(CFLAGS) -o $@ $<
+
+makedir/%.o: %.c
+	$(CC) -c $(CFLAGS) -o $@ $<
+
+makedir/%.d: %.c
+	$(CC) -MM $(CFLAGS) $< > $@.tmp
+	sed 's|\($*\)\.o[ :]*|\1.o $@ : |g' $@.tmp > $@
+	$(RM) -f $@.tmp
+
+include $(OBJS:.o=.d)
Index: /branches/rel3/psLib/src/collections/psArray.c
===================================================================
--- /branches/rel3/psLib/src/collections/psArray.c	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psArray.c	(revision 2163)
@@ -0,0 +1,136 @@
+
+/** @file  psArray.c
+ *
+ *  @brief Contains support for basic vector types
+ *
+ *  This file defines the basic type for a vector struct and functions useful
+ *  in manupulating vectors.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-28 23:26:48 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+
+/*  INCLUDE FILES                                                             */
+
+/******************************************************************************/
+#include<stdlib.h>                         // for qsort, etc.
+#include<string.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psArray.h"
+#include "psLogMsg.h"
+
+#include "psCollectionsErrors.h"
+
+/*****************************************************************************/
+
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+
+/*****************************************************************************/
+static void arrayFree(psArray* restrict psArr);
+
+/*****************************************************************************/
+
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+
+/*****************************************************************************/
+psArray* psArrayAlloc(unsigned int nalloc)
+{
+    psArray* psArr = NULL;
+
+    // Create vector struct
+    psArr = (psArray* ) psAlloc(sizeof(psArray));
+    p_psMemSetDeallocator(psArr, (psFreeFcn) arrayFree);
+
+    psArr->nalloc = nalloc;
+    psArr->n = nalloc;
+
+    // Create vector data array
+    psArr->data = psAlloc(nalloc * sizeof(psPTR));
+
+    return psArr;
+}
+
+psArray* psArrayRealloc(psArray* restrict in, unsigned int nalloc)
+{
+    if (in == NULL) {
+        return psArrayAlloc(nalloc);
+    } else if (in->nalloc != nalloc) {     // No need to realloc to same size
+        if (nalloc < in->n) {
+            for (int i = nalloc; i < in->n; i++) {      // For reduction in vector size
+                psFree(in->data[i]);
+            }
+            in->n = nalloc;
+        }
+        // Realloc after decrementation to avoid accessing freed array elements
+        in->data = psRealloc(in->data, nalloc * sizeof(psPTR));
+        in->nalloc = nalloc;
+    }
+
+    return in;
+}
+
+static void arrayFree(psArray* restrict psArr)
+{
+    if (psArr == NULL) {
+        return;
+    }
+
+    psArrayElementFree(psArr);
+
+    psFree(psArr->data);
+}
+
+bool psArrayRemove(psArray* psArr,
+                   psPTR data)
+{
+    bool success = false;
+
+    if (psArr == NULL) {
+        return success;
+    }
+
+    int n = psArr->n;
+    psPTR* psArrData = psArr->data;
+    for (int i = n-1; i<0; i--) {
+        if (psArrData[i] == data) {
+            memmove(psArrData[i],psArrData[i+1],(n-i-1)*sizeof(psPTR));
+            n--;
+            success = true;
+        }
+    }
+    psArr->n = n; // reset the array size to indicate the removed item(s)
+
+    return success;
+}
+
+void psArrayElementFree(psArray* restrict psArr)
+{
+
+    if (psArr == NULL) {
+        return;
+    }
+
+    for (int i = 0; i < psArr->n; i++) {
+        psFree(psArr->data[i]);
+        psArr->data[i] = NULL;
+    }
+}
+
+psArray* psArraySort(psArray* in, psComparePtrFcn compare)
+{
+    if (in == NULL) {
+        return NULL;
+    }
+
+    qsort(in->data, in->n, sizeof(psPTR), (int (*)(const void *, const void *))compare);
+
+    return in;
+}
Index: /branches/rel3/psLib/src/collections/psArray.h
===================================================================
--- /branches/rel3/psLib/src/collections/psArray.h	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psArray.h	(revision 2163)
@@ -0,0 +1,120 @@
+
+/** @file  psArray.h
+ *
+ *  @brief Contains basic array definitions and operations
+ *
+ *  This file defines the basic type for a array struct and functions useful
+ *  in manupulating arrays.
+ *
+ *  @ingroup Array
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-28 23:26:48 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ARRAY_H
+#define PS_ARRAY_H
+
+#include<stdbool.h>
+
+#include "psType.h"
+#include "psCompare.h"
+
+/// @addtogroup Array
+/// @{
+
+/** An array to support primitive types.
+ *
+ * Struct for maintaining an array of frequently used primitive types.
+ *
+ */
+typedef struct
+{
+    unsigned int nalloc;        ///< Total number of elements available.
+    unsigned int n;             ///< Number of elements in use.
+    psPTR* data;                ///< An Array of pointer elements
+}
+psArray;
+
+/*****************************************************************************/
+
+/* FUNCTION PROTOTYPES                                                       */
+
+/*****************************************************************************/
+
+/** Allocate an array.
+ *
+ * Uses psLib memory allocation functions to create an array collection of 
+ * data
+ *
+ * @return psArray* : Pointer to psArray.
+ *
+ */
+psArray* psArrayAlloc(
+    unsigned int nalloc                ///< Total number of elements to make available.
+);
+
+/** Reallocate an array.
+ *
+ * Uses psLib memory allocation functions to reallocate an array collection 
+ * of data. 
+ *
+ * @return psArray* : Pointer to psArray.
+ *
+ */
+psArray* psArrayRealloc(
+    psArray* restrict psArr,           ///< array to reallocate.
+    unsigned int nalloc                ///< Total number of elements to make available.
+);
+
+/** Remove an element from the array
+ *
+ *  Finds and removes the specified data pointer from the list.  
+ *
+ * @return bool:  TRUE if the specified data pointer was found and removed, 
+ *                otherwise FALSE.
+ *
+ */
+bool psArrayRemove(
+    psArray* psArr,                    ///< array to operate on
+    psPTR data                         ///< the data pointer to remove from psArray
+);
+
+/** Deallocate/Dereference elements of an array.
+ *
+ * Uses psLib memory allocation functions to deallocate/dereference elements 
+ * of a array of void pointers.  The array psArr is not freed, and its elements
+ * will all be set to NULL.
+ *
+ */
+void psArrayElementFree(
+    psArray* restrict psArr            ///< Void pointer array to destroy.
+);
+
+/** Sort the array according to an external compare function.
+ *
+ *  Sorts an array via the specification of a comparison function
+ *  to specify how the objects on the array should be sorted.
+ *
+ *  The comparison function must return an integer less than, equal to, or 
+ *  greater than zero if the first argument is considered to be respectively 
+ *  less than, equal to, or greater than the second. 
+ *
+ *  If two members compare as equal, their order in the sorted array is 
+ *  undefined.
+ *
+ *  @return psArray* The sorted array.
+ */
+psArray* psArraySort(
+    psArray* in,                       ///< input array to sort.
+    psComparePtrFcn compare            ///< the compare function
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/collections/psBitSet.c
===================================================================
--- /branches/rel3/psLib/src/collections/psBitSet.c	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psBitSet.c	(revision 2163)
@@ -0,0 +1,321 @@
+/** @file  psBitSet.c
+ *
+ *  @brief Creates an array of bytes of arbitrary length for storing individual bits.
+ *
+ *  Bit masks are useful tools for toggling various flags and options. This set of functions module provides
+ *  a mechanism to create an array of bits of arbitrary length and manipulate them with basic binary
+ *  operations. A print function is also provided to display the entire set of bits in binary format as a
+ *  string.
+ *
+ *  @author Ross Harman, MHPCC
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-21 23:17:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+#include <stdbool.h>
+
+#include "psBitSet.h"
+#include "psMemory.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psString.h"
+
+#include "psCollectionsErrors.h"
+
+enum {
+    UNKNOWN_OP,
+    AND_OP,
+    OR_OP,
+    XOR_OP,
+    NOT_OP
+};
+
+static void bitSetFree(psBitSet* restrict inBitSet);
+
+/** Private function to create a mask.
+ *
+ *  Creates an eight bit mask with the given bit set. All other bits in the byte are zero. The input bit uses
+ *  zero-based indexing, and is the cumulitive index within the array, not the localized byte's bit position.
+ *
+ *  @return  char*: Pointer to byte in which bit is contained.
+ */
+static char mask(int bit)
+{
+    char mask = (char)0x01;
+
+    // Ignore splint warning about negative bit shifts
+    /* @i@ */
+    mask = mask << (bit % 8);
+
+    return mask;
+}
+
+static void bitSetFree(psBitSet* restrict inBitSet)
+{
+    if (inBitSet == NULL) {
+        return;
+    }
+    psFree(inBitSet->bits);
+}
+
+psBitSet* psBitSetAlloc(int n)
+{
+    int numBytes = 0;
+    psBitSet* newObj = NULL;
+
+    if (n < 0) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetAlloc",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psBitSet_ALLOC_NEG_SIZE,
+                   n);
+        return NULL;
+    }
+
+    numBytes = ceil(n / 8.0);
+    newObj = psAlloc(sizeof(psBitSet));
+    p_psMemSetDeallocator(newObj, (psFreeFcn) bitSetFree);
+    newObj->n = numBytes;
+
+    // Ignore splint warning about releasing pointer members, since they've not been allocated yet
+    /* @i@ */
+    newObj->bits = psAlloc(sizeof(char) * numBytes);
+
+    memset(newObj->bits, 0, numBytes);
+
+    return newObj;
+}
+
+psBitSet* psBitSetSet(psBitSet* inBitSet,
+                      int bit)
+{
+    char *byte = NULL;
+
+    if (inBitSet == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetSet",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psBitSet_SET_NULL);
+        return inBitSet;
+    } else if ( (bit < 0) ||
+                (bit > inBitSet->n * 8 - 1) ) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetSet",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psBitSet_BIT_OUTOFRANGE,
+                   bit,inBitSet->n * 8 - 1);
+        return inBitSet;
+    }
+    // Variable byte is the byte in the array that contains the bit to be set
+    byte = inBitSet->bits + bit / 8;
+    *byte |= mask(bit);
+
+    return inBitSet;
+}
+
+psBitSet* psBitSetClear(psBitSet* inBitSet,
+                        int bit)
+{
+    char *byte = NULL;
+
+    if (inBitSet == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetClear",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psBitSet_SET_NULL);
+        return inBitSet;
+    } else if ( (bit < 0) ||
+                (bit > inBitSet->n * 8 - 1) ) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetClear",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psBitSet_BIT_OUTOFRANGE,
+                   bit,inBitSet->n * 8 - 1);
+        return inBitSet;
+    }
+    // Variable byte is the byte in the array that contains the bit to be set
+    byte = inBitSet->bits + bit / 8;
+    *byte &= ! mask(bit);
+
+    return inBitSet;
+}
+
+bool psBitSetTest(const psBitSet* inBitSet,
+                  int bit)
+{
+    char *byte = NULL;
+
+    if (inBitSet == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetTest",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psBitSet_SET_NULL);
+        return false;
+    } else if ( (bit < 0) ||
+                (bit > inBitSet->n * 8 - 1) ) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetTest",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psBitSet_BIT_OUTOFRANGE,
+                   bit,inBitSet->n * 8 - 1);
+        return false;
+    }
+
+    // Variable byte is the byte in the array that contains the bit to be tested
+    byte = inBitSet->bits + bit / 8;
+    return ((*byte & mask(bit)) != 0);
+}
+
+psBitSet* psBitSetOp(psBitSet* outBitSet,
+                     const psBitSet* restrict inBitSet1,
+                     char *operator,
+                     const psBitSet* restrict inBitSet2)
+{
+    int i = 0;
+    int n = 0;
+    char* outBits = NULL;
+    char* inBits1 = NULL;
+    char* inBits2 = NULL;
+    int op = UNKNOWN_OP;
+
+    if (inBitSet1 == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetOp",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psBitSet_FIRST_OPERAND_NULL);
+        psFree(outBitSet);
+        return NULL;
+    }
+    inBits1 = inBitSet1->bits;
+
+    if (operator == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetOp",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psBitSet_OPERATOR_NULL);
+        psFree(outBitSet);
+        return NULL;
+    }
+
+    // make operator all caps
+    int tempStrLen = strlen(operator);
+    char* tempStr = psAlloc(tempStrLen+1);
+
+    for (int lcv=0;lcv<tempStrLen;lcv++) {
+        tempStr[lcv] = (char)toupper(operator[lcv]);
+    }
+    tempStr[tempStrLen] = '\0';
+
+    // parse the operator
+    if (strcmp(operator,"AND")==0) {
+        op = AND_OP;
+    } else if (strcmp(operator,"OR")==0) {
+        op = OR_OP;
+    } else if (strcmp(operator,"XOR")==0) {
+        op = XOR_OP;
+    } else if (strcmp(operator,"NOT")==0) {
+        op = NOT_OP;
+    } else {
+        psFree(tempStr);
+        psFree(outBitSet);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetOp",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psBitSet_OPERATOR_INVALID,
+                   operator);
+        return NULL;
+    }
+    psFree(tempStr);
+
+    if (op != NOT_OP) {
+        if (inBitSet2 == NULL) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetOp",
+                       PS_ERR_BAD_PARAMETER_NULL, true,
+                       PS_ERRORTEXT_psBitSet_SECOND_OPERAND_NULL);
+            psFree(outBitSet);
+            return NULL;
+        }
+
+        if (inBitSet1->n != inBitSet2->n) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetOp",
+                       PS_ERR_BAD_PARAMETER_SIZE, true,
+                       PS_ERRORTEXT_psBitSet_OPERANDS_SIZE_DIFFER);
+            psFree(outBitSet);
+            return NULL;
+        }
+        inBits2 = inBitSet2->bits;
+    }
+
+    if (outBitSet == NULL) {
+        outBitSet = psBitSetAlloc(inBitSet1->n*8);
+    } else if (outBitSet->n != inBitSet1->n) {
+        outBitSet->n = inBitSet1->n;
+        outBitSet->bits = psRealloc(outBitSet->bits, inBitSet1->n);
+    }
+
+    n = outBitSet->n;
+    outBits = outBitSet->bits;
+
+    switch (op) {
+    case AND_OP:
+        for (i = 0; i < n; i++) {
+            outBits[i] = inBits1[i] & inBits2[i];
+        }
+        break;
+    case OR_OP:
+        for (i = 0; i < n; i++) {
+            outBits[i] = inBits1[i] | inBits2[i];
+        }
+        break;
+    case XOR_OP:
+        for (i = 0; i < n; i++) {
+            outBits[i] = inBits1[i] ^ inBits2[i];
+        }
+        break;
+    case NOT_OP:
+        for (i = 0; i < n; i++) {
+            outBits[i] = ~inBits1[i];
+        }
+        break;
+    default:
+        psAbort(PS_ERRORNAME_DOMAIN "psBitSetOp",
+                "Unexpected error - operator parsed successfully but not valid?");
+    }
+
+    return outBitSet;
+}
+
+psBitSet* psBitSetNot(psBitSet* outBitSet,
+                      const psBitSet* restrict inBitSet)
+{
+    if (inBitSet == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetNot",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psBitSet_OPERAND_NULL);
+        psFree(outBitSet);
+        return NULL;
+    }
+
+    outBitSet = psBitSetOp(outBitSet,inBitSet,"NOT",NULL);
+
+    if (outBitSet == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetNot",
+                   PS_ERR_UNKNOWN, false,
+                   PS_ERRORTEXT_psBitSet_NOT_OP_FAILED);
+    }
+
+    return outBitSet;
+}
+
+char *psBitSetToString(const psBitSet* restrict inBitSet)
+{
+    int i = 0;
+    int numBits = inBitSet->n * 8;
+    char *outString = psAlloc((size_t) numBits + 1);
+
+    for (i = 0; i < numBits; i++) {
+        outString[numBits - i - 1] = psBitSetTest(inBitSet, i) ? '1' : '0';
+    }
+
+    outString[numBits] = 0;
+
+    return outString;
+}
Index: /branches/rel3/psLib/src/collections/psBitSet.h
===================================================================
--- /branches/rel3/psLib/src/collections/psBitSet.h	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psBitSet.h	(revision 2163)
@@ -0,0 +1,143 @@
+/** @file  psBitSet.h
+ *
+ *  @brief Creates an array of bytes of arbitrary length for storing individual bits.
+ *
+ *  Bit masks are useful tools for toggling various flags and options. This set of functions module provides
+ *  a mechanism to create an array of bits of arbitrary length and manipulate them with basic binary
+ *  operations. A print function is also provided to display the entire set of bits in binary format as a
+ *  string.
+ *
+ *  @ingroup BitSet
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-14 20:01:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PSBITSET_H
+#define PSBITSET_H
+
+/// @addtogroup BitSet
+/// @{
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+/** Struct containing array of bytes to hold bit data and corresponding array length.
+ *
+ *  The bits in the struct are assembled in as an array of bytes with eight bits per byte. The bits are
+ *  arranged with the LSB in first (right most) position of the first array element.
+ */
+typedef struct
+{
+    int n;                             ///< Number of bytes in the array
+    char *bits;                        ///< Aray of bytes holding bits
+}
+psBitSet;
+
+/*****************************************************************************/
+/* FUNCTION PROTOTYPES                                                       */
+/*****************************************************************************/
+
+/** Allocate a psBitSet.
+ *
+ *  Create a psBitSet with the number of bits specified by the user. All bits are set to zero upon
+ *  allocation.
+ *
+ *  @return  psBitSet* : Pointer to struct containing array of bits and size of array.
+ */
+
+/*@null@*/
+psBitSet* psBitSetAlloc(
+    int n                              ///< Number of bits in psBitSet array
+);
+
+/** Set a bit.
+ *
+ *  Sets a bit at a given bit location. The bit is set based on a zero index with the
+ *  first bit set in the zero bit slot of the zero element of the byte array. As an example, setting bit 3 in
+ *  an array with two elements would result in an psBitSet that looks like 00000000 00001000.
+ *
+ *  @return  psBitSet* : Pointer to struct containing psBitSet.
+ */
+psBitSet* psBitSetSet(
+    /* @returned@ */
+    psBitSet* restrict inMask,         ///< Pointer to psBitSet to be set.
+    int bit                            ///< Bit to be set.
+);
+
+/** Clear a bit.
+ *
+ *  Clear a bit at a given bit location. The bit is cleared based on a zero 
+ *  index with the first bit set in the zero bit slot of the zero element of 
+ *  the byte array. 
+ *
+ *  @return  psBitSet* : Pointer to struct containing psBitSet.
+ */
+psBitSet* psBitSetClear(
+    /* @returned@ */
+    psBitSet* restrict inMask,         ///< Pointer to psBitSet to be cleared.
+    int bit                            ///< Bit to be cleared.
+);
+
+/** Test the value of a bit.
+ *
+ *  Prints the value of a bit at a given bit location, either one or zero. The resulting bit is based on a
+ *  zero index format with the first bit set in the zero bit slot of the zero element of the byte array
+ *  As an example, testing bit 3 in a psBitSet with two bytes that looks like 00000000 00001000 would return a
+ *  value of one, since that is the value that was set.
+ *
+ *  @return  int: Value of bit, either one or zero.
+ */
+
+bool psBitSetTest(
+    const psBitSet* restrict inMask,   ///< Pointer psBitSet to be tested.
+    int bit                            ///< Bit to be tested.
+);
+
+/** Perform a binary operation on two psBitSets
+ *
+ *  Perform an AND, OR, or XOR on two psBitSets. If the BitMasks are not the same size, the operation will not
+ *  be performed and an error message will be logged.
+ *
+ *  @return  psBitSet* : Pointer to struct containing result of binary operation.
+ */
+psBitSet* psBitSetOp(
+    /* @returned@ */
+    psBitSet* restrict outMask,        ///< Resulting psBitSet from binary operation
+    const psBitSet* restrict inMask1,  ///< First psBitSet on which to operate
+    char *operator,                    ///< Bit operation
+    const psBitSet* restrict inMask2   ///< First psBitSet on which to operate
+);
+
+/** Perform a not operation on a psBitSet
+ *
+ *  Toggles bits in a psBitset. All zero bits are set to one and all one bits are set to zero.
+ *
+ *  @return  psBitSet* : Pointer to struct containing result of operation.
+ */
+
+psBitSet* psBitSetNot(
+    psBitSet* outBitSet,               ///< Resulting psBitSet from operation
+    const psBitSet* restrict inBitSet  ///< Input psBitSet
+);
+
+/** Convert the psBitSet to a string of ones and zeros.
+ *
+ *  Converts the contents of a psBitSet to a string representation of its binary form of ones and zeros. The
+ *  LSB is the right-most chracter. Each set of eight characters represents one byte.
+ *
+ *  @return  char*: Pointer to character array containing string data.
+ */
+
+char *psBitSetToString(
+    const psBitSet* restrict inMask    ///< psBitSet to convert */
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/collections/psCollectionsErrors.dat
===================================================================
--- /branches/rel3/psLib/src/collections/psCollectionsErrors.dat	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psCollectionsErrors.dat	(revision 2163)
@@ -0,0 +1,32 @@
+#
+#  This file is used to generate psCollectionsErrors.h content
+#
+#  Format is:
+#  ERRORNAME(one word)    ERRORTEXT
+#
+#  N.B. in code, the ERRORNAME appears as PS_ERRORTEXT_ERRORNAME
+####################################################################
+#
+psVector_REALLOC_NULL                  psVectorRealloc must a given a non-NULL psVector to resize.  Desired datatype unknown.
+psVector_NOT_A_VECTOR                  The input psVector must have a vector dimension type.
+psVector_SORT_NULL                     psVectorSort can not sort a NULL psVector.
+psVector_UNSUPPORTED_TYPE              Input psVector is an unsupported type (%d).
+#
+psBitSet_ALLOC_NEG_SIZE                The number of bit in a psBitSet (%d) must be greater than zero.
+psBitSet_SET_NULL                      Can not operate on a NULL psBitSet.
+psBitSet_BIT_OUTOFRANGE                The specified bit position (%d) is invalid.  Position must be between 0 and %d.
+psBitSet_OPERATOR_NULL                 Specified operator is NULL.  Must specify desired operator.
+psBitSet_OPERATOR_INVALID              Specified operator, %s, is invalid.  Valid operators are AND, OR, and XOR.
+psBitSet_FIRST_OPERAND_NULL            First psBitSet operand can not be NULL.
+psBitSet_SECOND_OPERAND_NULL           Second psBitSet operand can not be NULL.
+psBitSet_OPERANDS_SIZE_DIFFER          The psBitSet operand must be the same size.
+psBitSet_NOT_OP_FAILED                 Could not perform NOT operation.
+psBitSet_OPERAND_NULL                  Operand can not be NULL.
+#
+psScalar_UNSUPPORTED_TYPE              Specified datatype (%d) is unsupported by psScalar.
+psScalar_COPY_NULL                     Can not copy a NULL psScalar.
+#
+psHash_KEY_NULL                        Input key can not be NULL.
+psHash_TABLE_NULL                      Input psHash can not be NULL.
+psHash_DATA_NULL                       Input data can not be NULL.
+
Index: /branches/rel3/psLib/src/collections/psCollectionsErrors.h
===================================================================
--- /branches/rel3/psLib/src/collections/psCollectionsErrors.h	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psCollectionsErrors.h	(revision 2163)
@@ -0,0 +1,53 @@
+/** @file  psCollectionsErrors.h
+ *
+ *  @brief Contains the error text for the collections functions
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-07 19:51:30 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_COLLECTIONS_ERRORS_H
+#define PS_COLLECTIONS_ERRORS_H
+
+/* N.B., lines between '//~Start' and '//~End' are automatic generated from
+ * the template following the '//~Start'.  The template is used to generate
+ * the other lines by, for each error text in psCollectionsErrors.dat, the following
+ * substitutions are made:
+ *     $1  The error text macro name (first word in the psCollectionsErrors.dat lines)
+ *     $2  The error text (rest of the line in psCollectionsErrors.dat)
+ *     $n  The order of the source line in psCollecitonsErrors.dat (comments excluded)
+ * 
+ * DO NOT EDIT THE LINES BETWEEN //~Start and //~End!  ANY CHANGES WILL BE OVERWRITTEN.
+ */
+
+#define PS_ERRORNAME_DOMAIN "psLib.collections."
+
+//~Start #define PS_ERRORTEXT_$1 "$2"
+#define PS_ERRORTEXT_psVector_REALLOC_NULL "psVectorRealloc must a given a non-NULL psVector to resize.  Desired datatype unknown."
+#define PS_ERRORTEXT_psVector_NOT_A_VECTOR "The input psVector must have a vector dimension type."
+#define PS_ERRORTEXT_psVector_SORT_NULL "psVectorSort can not sort a NULL psVector."
+#define PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE "Input psVector is an unsupported type (%d)."
+#define PS_ERRORTEXT_psBitSet_ALLOC_NEG_SIZE "The number of bit in a psBitSet (%d) must be greater than zero."
+#define PS_ERRORTEXT_psBitSet_SET_NULL "Can not operate on a NULL psBitSet."
+#define PS_ERRORTEXT_psBitSet_BIT_OUTOFRANGE "The specified bit position (%d) is invalid.  Position must be between 0 and %d."
+#define PS_ERRORTEXT_psBitSet_OPERATOR_NULL "Specified operator is NULL.  Must specify desired operator."
+#define PS_ERRORTEXT_psBitSet_OPERATOR_INVALID "Specified operator, %s, is invalid.  Valid operators are AND, OR, and XOR."
+#define PS_ERRORTEXT_psBitSet_FIRST_OPERAND_NULL "First psBitSet operand can not be NULL."
+#define PS_ERRORTEXT_psBitSet_SECOND_OPERAND_NULL "Second psBitSet operand can not be NULL."
+#define PS_ERRORTEXT_psBitSet_OPERANDS_SIZE_DIFFER "The psBitSet operand must be the same size."
+#define PS_ERRORTEXT_psBitSet_NOT_OP_FAILED "Could not perform NOT operation."
+#define PS_ERRORTEXT_psBitSet_OPERAND_NULL "Operand can not be NULL."
+#define PS_ERRORTEXT_psScalar_UNSUPPORTED_TYPE "Specified datatype (%d) is unsupported by psScalar."
+#define PS_ERRORTEXT_psScalar_COPY_NULL "Can not copy a NULL psScalar."
+#define PS_ERRORTEXT_psHash_KEY_NULL "Input key can not be NULL."
+#define PS_ERRORTEXT_psHash_TABLE_NULL "Input psHash can not be NULL."
+#define PS_ERRORTEXT_psHash_DATA_NULL "Input data can not be NULL."
+//~End
+
+#endif
Index: /branches/rel3/psLib/src/collections/psCompare.c
===================================================================
--- /branches/rel3/psLib/src/collections/psCompare.c	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psCompare.c	(revision 2163)
@@ -0,0 +1,80 @@
+
+/** @file psCompare.c
+ *  @brief Comparison functions for sorting routines
+ *  @ingroup Compare
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-07 00:06:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "psType.h"
+#include "psCompare.h"
+
+#define COMPARE_NUMERIC_PTR(TYPE) \
+int psCompare##TYPE##Ptr(const void** a, const void** b) { \
+    return **((ps##TYPE**)a) - **((ps##TYPE**)b); \
+}
+
+#define COMPARE_NUMERIC_PTR_DESCENDING(TYPE) \
+int psCompareDescending##TYPE##Ptr(const void** a, const void** b) { \
+    return **((ps##TYPE**)b) - **((ps##TYPE**)a); \
+}
+
+#define COMPARE_NUMERIC(TYPE) \
+int psCompare##TYPE(const void* a, const void* b) { \
+    return *((ps##TYPE*)a) - *((ps##TYPE*)b); \
+}
+
+#define COMPARE_NUMERIC_DESCENDING(TYPE) \
+int psCompare##TYPE##Descending(const void* a, const void* b) { \
+    return *((ps##TYPE*)b) - *((ps##TYPE*)a); \
+}
+
+COMPARE_NUMERIC_PTR(S8)
+COMPARE_NUMERIC_PTR(S16)
+COMPARE_NUMERIC_PTR(S32)
+COMPARE_NUMERIC_PTR(S64)
+COMPARE_NUMERIC_PTR(U8)
+COMPARE_NUMERIC_PTR(U16)
+COMPARE_NUMERIC_PTR(U32)
+COMPARE_NUMERIC_PTR(U64)
+COMPARE_NUMERIC_PTR(F32)
+COMPARE_NUMERIC_PTR(F64)
+
+COMPARE_NUMERIC_PTR_DESCENDING(S8)
+COMPARE_NUMERIC_PTR_DESCENDING(S16)
+COMPARE_NUMERIC_PTR_DESCENDING(S32)
+COMPARE_NUMERIC_PTR_DESCENDING(S64)
+COMPARE_NUMERIC_PTR_DESCENDING(U8)
+COMPARE_NUMERIC_PTR_DESCENDING(U16)
+COMPARE_NUMERIC_PTR_DESCENDING(U32)
+COMPARE_NUMERIC_PTR_DESCENDING(U64)
+COMPARE_NUMERIC_PTR_DESCENDING(F32)
+COMPARE_NUMERIC_PTR_DESCENDING(F64)
+
+COMPARE_NUMERIC(S8)
+COMPARE_NUMERIC(S16)
+COMPARE_NUMERIC(S32)
+COMPARE_NUMERIC(S64)
+COMPARE_NUMERIC(U8)
+COMPARE_NUMERIC(U16)
+COMPARE_NUMERIC(U32)
+COMPARE_NUMERIC(U64)
+COMPARE_NUMERIC(F32)
+COMPARE_NUMERIC(F64)
+
+COMPARE_NUMERIC_DESCENDING(S8)
+COMPARE_NUMERIC_DESCENDING(S16)
+COMPARE_NUMERIC_DESCENDING(S32)
+COMPARE_NUMERIC_DESCENDING(S64)
+COMPARE_NUMERIC_DESCENDING(U8)
+COMPARE_NUMERIC_DESCENDING(U16)
+COMPARE_NUMERIC_DESCENDING(U32)
+COMPARE_NUMERIC_DESCENDING(U64)
+COMPARE_NUMERIC_DESCENDING(F32)
+COMPARE_NUMERIC_DESCENDING(F64)
Index: /branches/rel3/psLib/src/collections/psCompare.h
===================================================================
--- /branches/rel3/psLib/src/collections/psCompare.h	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psCompare.h	(revision 2163)
@@ -0,0 +1,506 @@
+#if !defined(PS_COMPARE_H)
+#define PS_COMPARE_H
+
+/** @file psCompare.h
+ *  @brief Comparison functions for sorting routines
+ *
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @ingroup Compare
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-11 19:58:11 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/** @addtogroup Compare
+*  @{
+*/
+
+/** A comparison function for sorting elements that are pointers to data,
+ *  e.g., for psList of pointers to numeric values.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+typedef int (*psComparePtrFcn) (
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** A comparison function for sorting.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+typedef int (*psCompareFcn) (
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+/** Compare function of psS8 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareS8Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psS16 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareS16Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psS32 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareS32Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psS64 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareS64Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psU8 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareU8Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psU16 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareU16Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psU32 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareU32Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psU64 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareU64Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psF32 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareF32Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psF64 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareF64Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psS8 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingS8Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psS16 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingS16Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psS32 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingS32Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psS64 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingS64Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psU8 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingU8Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psU16 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingU16Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psU32 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or lessg than the second. 
+ */
+int psCompareDescendingU32Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psU64 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or lessg than the second. 
+ */
+int psCompareDescendingU64Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psF32 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or lessg than the second. 
+ */
+int psCompareDescendingF32Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psF64 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or lessg than the second. 
+ */
+int psCompareDescendingF64Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psS8 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareS8(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psS16 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareS16(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psS32 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareS32(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psS64 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareS64(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psU8 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareU8(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psU16 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareU16(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psU32 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareU32(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psU64 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareU64(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psF32 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareF32(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psF64 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareF64(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psS8 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingS8(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psS16 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingS16(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psS32 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingS32(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psS64 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingS64(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psU8 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingU8(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psU16 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingU16(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psU32 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingU32(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psU64 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingU64(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psF32 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingF32(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psF64 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingF64(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/collections/psHash.c
===================================================================
--- /branches/rel3/psLib/src/collections/psHash.c	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psHash.c	(revision 2163)
@@ -0,0 +1,437 @@
+
+/** @file  psHash.c
+*
+*  @brief Contains support for basic hashing functions.
+*
+*  This file will hold the functions for defining a hash table with arbitrary
+*  data types, allocating/deallocating that hash table, adding and removing
+*  data from that hash table, and listing all keys defined in the hash table.
+*
+*  @author Robert Lupton, Princeton University
+*  @author George Gusciora, MHPCC
+*
+*  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-09-21 23:17:53 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include "psHash.h"
+#include "psMemory.h"
+#include "psString.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psAbort.h"
+
+#include "psCollectionsErrors.h"
+
+static psHashBucket* hashBucketAlloc(const char *key, void *data, psHashBucket* next);
+static void hashBucketFree(psHashBucket* bucket);
+static void *doHashWork(psHash* table, const char *key, void *data, bool remove
+                           );
+static void hashFree(psHash* table);
+
+/******************************************************************************
+psHashKeyList(table): this function creates a linked list with an entry in
+that list for every key in the hash table.
+Inputs:
+    table: a hash table
+Return;
+    The linked list
+ *****************************************************************************/
+psList* psHashKeyList(psHash* table)
+{
+    int i = 0;                  // Loop index variable
+    psList* myLinkList = NULL;  // The output data structure
+    psHashBucket* ptr = NULL;   // Used to step thru linked list.
+
+    if (table == NULL) {
+        return NULL;
+    }
+    // Create the linked list
+    myLinkList = psListAlloc(NULL);
+
+    // Loop through every bucket in the hash table.  If that bucket is not
+    // NULL, then add the bucket's key to the linked list.
+    for (i = 0; i < table->nbucket; i++) {
+        if (table->buckets[i] != NULL) {
+            // Since a bucket contains a linked list of keys/data, we must
+            // step trough each key in that linked list:
+
+            ptr = table->buckets[i];
+            while (ptr != NULL) {
+                psListAdd(myLinkList, PS_LIST_HEAD, ptr->key);
+                ptr = ptr->next;
+            }
+        }
+    }
+
+    // Return the linked list
+    return (myLinkList);
+}
+
+/******************************************************************************
+hashBucketAlloc(key, data, next): This procedure creates a new hash bucket
+with the specified key, data, and next.
+Inputs:
+    key:  the new bucket's key pointer
+    data: the new bucket's data pointer
+    next: the new bucket's key pointer
+Return:
+    the new hash bucket.
+ *****************************************************************************/
+static psHashBucket* hashBucketAlloc(const char *key,
+                                     void *data,
+                                     psHashBucket* next)
+{
+    // Allocate memory for the new hash bucket.
+    psHashBucket* bucket = psAlloc(sizeof(psHashBucket));
+
+    p_psMemSetDeallocator(bucket, (psFreeFcn) hashBucketFree);
+
+    // Initialize the bucket.
+    bucket->key = psStringCopy(key);
+
+    if (data == NULL) {
+        // NOTE: Should we flag a warning message?
+        bucket->data = NULL;
+    } else {
+        bucket->data = psMemIncrRefCounter(data);
+    }
+
+    bucket->next = next;
+
+    return bucket;
+}
+
+/******************************************************************************
+hashBucketFree(bucket): This procedure deallocates the specified
+hash bucket.
+Inputs:
+    bucket: the hash bucket to be freed.
+Return:
+    NONE
+ *****************************************************************************/
+static void hashBucketFree(psHashBucket* bucket)
+{
+    if (bucket == NULL) {
+        return;
+    }
+
+    psFree(bucket->key);
+
+    psFree(bucket->data);
+}
+
+/******************************************************************************
+psHashAlloc(nbucket): this procedure creates a new hash table with the
+specified number of buckets.
+Inputs:
+    nbucket: initial number of buckets
+Return:
+    The new hash table.
+ *****************************************************************************/
+psHash* psHashAlloc(int nbucket)        // initial number of buckets
+{
+    int i = 0;                  // loop index variable
+
+    // Create the new hash table.
+    psHash* table = psAlloc(sizeof(psHash));
+
+    p_psMemSetDeallocator(table, (psFreeFcn) hashFree);
+
+    // Allocate memory for the buckets.
+    table->buckets = psAlloc(nbucket * sizeof(psHashBucket* ));
+    table->nbucket = nbucket;
+
+    psTrace("utils.hash", 1, "Creating %d-element hash table\n", nbucket);
+
+    // Initialize all buckets to NULL.
+    for (i = 0; i < nbucket; i++)
+    {
+        table->buckets[i] = NULL;
+    }
+
+    // Return the new hash table.
+    return table;
+}
+
+/******************************************************************************
+psHashFree(table, itemFree): This procedure deallocates the specified hash
+table.  It loops through each bucket, and calls hashBucketFree() on that
+bucket.
+ 
+Inputs:
+    table: a hash table
+Return:
+    NONE
+ *****************************************************************************/
+static void hashFree(psHash* table)
+{
+    int i = 0;                  // Loop index variable.
+
+    if (table == NULL) {
+        return;
+    }
+    // Loop through each bucket in the hash table.  If that bucket is not
+    // NULL, then free the bucket via a function call to hashBucketFree();
+    for (i = 0; i < table->nbucket; i++) {
+
+        // A bucket is composed of a linked list of buckets.
+        while (table->buckets[i] != NULL) {
+            psHashBucket* bucket = table->buckets[i];
+            table->buckets[i] = bucket->next;
+            psFree(bucket);
+        }
+    }
+
+    // Free the bucket structure, then the hash table.
+    psFree(table->buckets);
+}
+
+/******************************************************************************
+doHashWork(table, key, data, remove): This is an internal
+procedure which does the bulk of the work in using the hash table.  Depending
+upon the input parameters, it will either insert a new key/data into the hash
+table, retrieve the data for a specified key, or remove a key/data item.  If
+we try to insert a key that already exists in the hash table, then we deallocate
+the existing data/key item.
+Inputs:
+    table: a hash table
+    key: the key to insert, retrieve, or remove.  Must not be NULL.
+    data: the data to insert, if not NULL
+    remove: set to non-zero if the key/data should be removed from the table.
+Return:
+    NONE
+ 
+NOTE: consider removing this private function and simply putting the code
+into the psHashInsert(), psHashLookup(), and psHashRemove().  Why?  Because
+there is little common code between those functions.
+  *****************************************************************************/
+static void *doHashWork(psHash* table,
+                        const char *key,
+                        void *data, bool remove
+                           )
+{
+    long int hash = 1;          // This will contain an integer value
+
+    // "hashed" from the key.
+    char *tmpchar = NULL;       // Used in computing the hash function.
+    psHashBucket* ptr = NULL;   // Used to retrieve the hash bucket.
+    psHashBucket* optr = NULL;  // "original pointer": used to step
+
+    // thru the linked list for a bucket.
+
+    // The following condition should never be true, since this is a private
+    // function, but I'm checking it anyway since future coders might change
+    // the way this procedure is called.
+    if ((table == NULL) || (key == NULL)) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "doHashWork",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psHash_KEY_NULL);
+        return NULL;
+    }
+    // NOTE: This is the originally supplied hash function.
+    // for (int i = 0, len = strlen(key); i < len; i++) {
+    // hash = (hash << 1) ^ key[i];
+    // }
+    // hash &= (table->nbucket - 1);
+
+    // This hash algorithm is from Sedgewick.  NOTE: must reread to ensure that
+    // the size of the hash table is not required to be a prime number.
+    tmpchar = (char *)key;
+    for (hash = 0; *tmpchar != '\0'; tmpchar++) {
+        hash = (64 * hash + *tmpchar) % (table->nbucket);
+    }
+
+    // NOTE: This should not be necessary, but for now, I'm checking bounds
+    // anyway.
+    if ((hash < 0) || (hash >= table->nbucket)) {
+        psAbort(__func__, "Internal hash function out of range (%d)", hash);
+    }
+    // ptr will have the correct hash bucket.
+    ptr = table->buckets[hash];
+
+    // We know the correct hash bucket, now we need to know what to do.
+    // If the data parameter is NULL, then, by definition, this is a retrieve
+    // or a remove operation on the hash table.
+
+    if (data == NULL) {
+        if (remove
+           ) {
+            // We search through the linked list for this bucket in
+            // the hash table and look for an entry for this key.
+
+            optr = ptr;
+            while (ptr != NULL) {
+                // Determine if this entry holds the correct key.
+                if (strcmp(key, ptr->key) == 0) {
+                    // The following lines of code are fairly standard ways
+                    // of removing an item from a single-linked list.
+
+                    void *data = ptr->data;
+
+                    optr->next = ptr->next;
+                    if (ptr == table->buckets[hash]) {
+                        table->buckets[hash] = ptr->next;
+                    }
+                    psFree(ptr);
+
+                    // By definition, the data associated with that key
+                    // must be returned, not freed.
+                    return data;
+                }
+                optr = ptr;
+                ptr = ptr->next;
+            }
+            return NULL;                   // not in hash
+        }
+        else {
+            // If we get here, then a retrieve operation is requested.  So,
+            // we step trough the linked list at this bucket, and return the
+            // data once we find it, or return NULL if we don't.
+            while (ptr != NULL) {
+                if (strcmp(key, ptr->key) == 0) {
+                    return ptr->data;
+                }
+                ptr = ptr->next;
+            }
+            return NULL;                   // not in hash
+        }
+    } else {
+        // We get here if this procedure was called with non-NULL data.
+        // Therefore, we should insert that data into the hash table.
+        // First, we search through the linked list for this bucket in
+        // the hash table and look for a duplicate entry for this key.
+
+        while (ptr != NULL) {
+            if (strcmp(key, ptr->key) == 0) {
+                // We have found this key in the hash table.
+
+                psTrace("utils.hash.insert", 3, "Replacing data for %s\n", key);
+
+                // NOTE: I have changed this behavior from the originally
+                // supplied code.  Formerly, if itemFree was NULL, then
+                // the new data was not inserted into the hash table.
+
+                psFree(ptr->data);
+
+                ptr->data = psMemIncrRefCounter(data);
+                return data;
+            }
+            ptr = ptr->next;
+        }
+        // We did not found key in the linked list for this bucket of the hash
+        // table.  So, we insert this data at the head of that linked list.
+
+        table->buckets[hash] = hashBucketAlloc(key, data, table->buckets[hash]);
+        return data;
+    }
+}
+
+/******************************************************************************
+psHashInsert(table, key, data, itemFree): this procedure, which is part of
+the public API, inserts a new key/data pair into the hash table.
+Inputs:
+    table: a hash table
+    key: the key to use
+    data: the data to insert.
+    itemFree: a function pointer
+Return:
+    boolean value defining success or failure
+ *****************************************************************************/
+bool psHashAdd(psHash* table,
+               const char *key,
+               void *data)
+{
+    if (table == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psHashAdd",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psHash_KEY_NULL);
+        return false;
+    }
+    if (key == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psHashAdd",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psHash_TABLE_NULL);
+        return false;
+    }
+    if (data == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psHashAdd",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psHash_DATA_NULL);
+    }
+
+    return (doHashWork(table, key, data, 0) != NULL);
+}
+
+/******************************************************************************
+psHashLookup(table, key): this procedure, which is part of the public API,
+looks up the specified key in the hash table and returns the data associated
+with that key.
+ 
+Inputs:
+    table: a hash table
+    key: the key to use
+Return:
+    The data associated with that key.
+ *****************************************************************************/
+void *psHashLookup(psHash* table,      // table to lookup key in
+                   const char *key)     // key to lookup
+{
+    if (table == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psHashLookup",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psHash_KEY_NULL);
+        return NULL;
+    }
+    if (key == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psHashLookup",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psHash_TABLE_NULL);
+        return NULL;
+    }
+
+    return doHashWork(table, key, NULL, 0);
+}
+
+/******************************************************************************
+psHashRemove(table, key, itemFree): this procedure, which is part of the
+public API, removes the specified key from the hash table.
+Inputs:
+    table: a hash table
+    key: the key to remove
+    itemFree: a function pointer
+Return:
+    boolean value defining success or failure
+ *****************************************************************************/
+bool psHashRemove(psHash* table,
+                  const char *key)
+{
+    void *data = NULL;
+    bool retVal = false;
+
+    if (table == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psHashRemove",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psHash_TABLE_NULL);
+        return false;
+    }
+    if (key == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psHashRemove",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psHash_KEY_NULL);
+        return false;
+    }
+
+    data = doHashWork(table, key, NULL, 1);
+    if (data != NULL) {
+        retVal = true;
+    } else {
+        retVal = false;
+    }
+    return retVal;
+}
Index: /branches/rel3/psLib/src/collections/psHash.h
===================================================================
--- /branches/rel3/psLib/src/collections/psHash.h	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psHash.h	(revision 2163)
@@ -0,0 +1,73 @@
+
+/** @file  psHash.h
+ *  @brief Contains support for basic hashing functions.
+ *  @ingroup HashTable
+ *
+ *  This file will hold the prototypes for defining a hash table with arbitrary
+ *  data types, allocating/deallocating that has table, adding and removing
+ *  data from that hash table, and listing all keys defined in the hash table.
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *   
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-09 23:40:55 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_HASH_H)
+#define PS_HASH_H
+
+/** \addtogroup HashTable
+ *  \{
+ */
+#include<stdbool.h>
+
+#include "psList.h"
+
+/** A bucket that holds an item of data. */
+typedef struct psHashBucket
+{
+    char *key;                  ///< key for this item of data
+    void *data;                 ///< the data itself
+    struct psHashBucket* next;  ///< list of other possible keys
+}
+psHashBucket;
+
+//typedef struct HashTable psHash; ///< Opaque type for a hash table
+
+/** The hash-table itself. */
+typedef struct psHash
+{
+    int nbucket;                ///< Number of buckets in hash table.
+    psHashBucket* *buckets;     ///< The bucket data.
+}
+psHash;
+
+/// Allocate hash buckets in table.
+psHash* psHashAlloc(int nbucket ///< The number of buckets to allocate.
+                   );
+
+/// Insert entry into table.
+bool psHashAdd(psHash* table,  ///< table to insert in
+               const char *key, ///< key to use
+               void *data       ///< data to insert
+              );
+
+/// Lookup key in table.
+void *psHashLookup(psHash* table,      ///< table to lookup key in
+                   const char *key      ///< key to lookup
+                  );
+
+/// Remove key from table.
+bool psHashRemove(psHash* table,       ///< table to lookup key in
+                  const char *key       ///< key to lookup
+                 );
+
+/// List all keys in table.
+psList* psHashKeyList(psHash* table    ///< table to list keys from.
+                     );
+
+/* \} */// End of DataGroup Functions
+
+#endif
Index: /branches/rel3/psLib/src/collections/psList.c
===================================================================
--- /branches/rel3/psLib/src/collections/psList.c	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psList.c	(revision 2163)
@@ -0,0 +1,475 @@
+/** @file psList.c
+ *  @brief Support for doubly linked lists
+ *  @ingroup LinkedList
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.19 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-14 20:01:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <pthread.h>                       // we need a mutex to make this stuff thread safe.
+
+#include "psError.h"
+#include "psAbort.h"
+#include "psMemory.h"
+#include "psList.h"
+#include "psTrace.h"
+#include "psLogMsg.h"
+
+#include "psCollectionsErrors.h"
+
+#define ITER_INIT_HEAD ((void *)1)         // next iteration should return head
+#define ITER_INIT_TAIL ((void *)2)         // next iteration should return tail
+
+// private functions.
+static psListElem* listGetIterator(psList* list);
+static int listGetIteratorIndex(psList* list);
+static void listSetIterator(psList* list, int where, bool lockList);
+static void listFree(psList* list);
+
+psList* psListAlloc(void *data)
+{
+    psList* list = psAlloc(sizeof(psList));
+
+    p_psMemSetDeallocator(list, (psFreeFcn) listFree);
+
+    list->size = 0;
+    list->head = list->tail = NULL;
+    list->iter = ITER_INIT_HEAD;
+    list->iterIndex = PS_LIST_HEAD;
+
+    pthread_mutex_init(&(list->lock), NULL)
+    ;
+
+    if (data != NULL) {
+        psListAdd(list, PS_LIST_TAIL, data);
+    }
+
+    return list;
+}
+
+static void listFree(psList* list)
+{
+    if (list == NULL) {
+        return;
+    }
+
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    for (psListElem* ptr = list->head; ptr != NULL;) {
+        psListElem* next = ptr->next;
+
+        psFree(ptr->data);
+        psFree(ptr);
+
+        ptr = next;
+    }
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    pthread_mutex_destroy(&list->lock)
+    ;
+
+}
+
+bool psListAdd(psList* list, int location, void *data)
+{
+    psListElem* position;
+    psListElem* elem;
+    int cursorIndex = 0;
+
+    if (list == NULL) {
+        return false;
+    }
+
+    if (data == NULL) {
+        return false;
+    }
+
+    if (location <= PS_LIST_UNKNOWN) {
+        // / XXX What is the better way to communicate this failure to the caller?
+        psLogMsg(__func__, PS_LOG_WARN, "The given insert location (%i) for psListAdd is invalid.", location);
+        return false;
+    }
+
+    elem = psAlloc(sizeof(psListElem));
+
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    if (location > 0 && location > list->size) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "Invalid index %d (only %d elements in psList); assuming tail.", location, list->size);
+        location = PS_LIST_TAIL;
+    }
+
+    if (location == PS_LIST_TAIL || list->size == 0) {
+        // insert the element at the end of the list
+        elem->prev = list->tail;
+        elem->next = NULL;
+
+        if (list->tail != NULL) {
+            list->tail->next = elem;
+        }
+
+        if (list->head == NULL) {
+            list->head = elem;
+        }
+        list->tail = elem;
+
+        list->size++;
+        list->iter = elem;
+        list->iterIndex = list->size - 1;
+    } else {
+        // move ourselves to the given position
+        listSetIterator(list, location, false);
+        position = listGetIterator(list);
+        cursorIndex = listGetIteratorIndex(list);
+
+        if (position == NULL) {
+            psError(__func__, "%s failed to move cursor to specified location (%d)", __func__, location);
+            position = list->head;         // since we no list->size != 0, this must be non-NULL
+        }
+        // insert our new element in front of the given position
+        elem->prev = position->prev;
+        elem->next = position;
+        position->prev = elem;
+
+        if (elem->prev == NULL) {          // must be front of list
+            list->head = elem;
+        } else {
+            elem->prev->next = elem;
+        }
+
+        list->size++;
+        list->iter = elem;
+        list->iterIndex = cursorIndex;
+    }
+
+    elem->data = psMemIncrRefCounter(data);
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    return true;
+}
+
+
+/*
+ * Remove an element from a list
+ */
+bool psListRemove(psList* list, int location, void *data)
+{
+    psListElem* elem = NULL;    // element to remove
+    int cursorIndex = 0;
+
+    if (list == NULL) {
+        psError(__func__, "list parameter found to be NULL in %s", __func__);
+        return false;
+    }
+    // get exclusive access to list so that other threads will not get in the way.
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    if (location == PS_LIST_UNKNOWN) {
+        // search list for the data item.
+
+        int i = 0;              // index
+
+        for (psListElem* ptr = list->head; ptr != NULL; ptr = ptr->next) {
+            if (ptr->data == data) {
+                location = i;
+                break;
+            }
+            i++;
+        }
+
+        if (location == PS_LIST_UNKNOWN) {
+            psError(__func__, "Failed to find item in given psList.");
+            pthread_mutex_unlock(&list->lock)
+            ;
+            return false;
+        }
+    }
+    // position the list's cursor to the desired location
+    listSetIterator(list, location, false);
+    elem = listGetIterator(list);
+    cursorIndex = listGetIteratorIndex(list);
+
+    if (elem == NULL) {
+        psError(__func__, "Couldn't position to given index (%d) to remove element from list.", location);
+        pthread_mutex_unlock(&list->lock)
+        ;
+        return false;
+    }
+
+    list->size--;
+
+    if (elem->prev == NULL) {              // head of list?
+        list->head = elem->next;
+    } else {
+        elem->prev->next = elem->next;
+    }
+
+    if (elem->next == NULL) {              // tail of list?
+        list->tail = elem->prev;
+
+        // removed tail, so iter should be the last element of list to keep it valid
+        if (list->size > 0) {
+            list->iter = list->tail;
+            list->iterIndex = list->size - 1;
+        } else {
+            list->iter = ITER_INIT_TAIL;
+        }
+    } else {
+        elem->next->prev = elem->prev;
+        list->iter = elem->next;
+        list->iterIndex = cursorIndex;
+    }
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    // OK, delete list element and its data
+    psFree(elem->data);
+    psFree(elem);
+
+    return true;
+}
+
+void psListSetIterator(psList* list, int where)
+{
+    listSetIterator(list, where, true);
+}
+
+static void listSetIterator(psList* list, int where, bool lockList)
+{
+    psListElem* cursor;
+    int position;
+
+    if (list == NULL) {
+        psError(__func__, "Unexpected null pointer for psList parameter (%s:%d).", __FILE__, __LINE__);
+        return;
+    }
+
+    if (where == PS_LIST_CURRENT) {
+        return;
+    }
+
+    if (lockList) {
+        pthread_mutex_lock(&list->lock)
+        ;
+        // don't want the list changing on us while we move about
+    }
+
+    if (where >= (int)list->size) {
+        list->iter = NULL;
+        if (lockList) {
+            pthread_mutex_unlock(&list->lock)
+            ;
+        }
+        return;
+    }
+
+    switch (where) {
+    case PS_LIST_HEAD:
+        list->iter = ITER_INIT_HEAD;
+        break;
+
+    case PS_LIST_TAIL:
+        list->iter = ITER_INIT_TAIL;
+        break;
+
+    case PS_LIST_PREVIOUS:
+        cursor = listGetIterator(list);
+        position = listGetIteratorIndex(list);
+
+        if (cursor != NULL) {
+            list->iter = cursor->prev;
+            list->iterIndex = position - 1;
+        }
+        break;
+
+    case PS_LIST_NEXT:
+        cursor = listGetIterator(list);
+        position = listGetIteratorIndex(list);
+
+        if (cursor != NULL) {
+            list->iter = cursor->next;
+            list->iterIndex = position + 1;
+        }
+        break;
+
+    case PS_LIST_CURRENT:
+        break;
+
+    default:
+        if (where <= PS_LIST_HEAD) {   // bascially same as PS_LIST_UNKNOWN above
+            psError(__func__, "Can't move to an unknown position.  Not moving the iterator position.");
+        } else {
+            cursor = listGetIterator(list);
+            if (cursor == NULL) {      // reset the iterator if it is invalid
+                list->iter = ITER_INIT_HEAD;
+                list->iterIndex = 0;
+            }
+
+            int position = listGetIteratorIndex(list);
+
+            if (where < position) {
+                int diff = position - where;
+
+                for (int count = 0; count < diff; count++) {
+                    listSetIterator(list, PS_LIST_PREVIOUS, false);
+                }
+            } else {
+                int diff = where - position;
+
+                for (int count = 0; count < diff; count++) {
+                    listSetIterator(list, PS_LIST_NEXT, false);
+                }
+            }
+        }
+        break;
+    }
+
+    if (lockList) {
+        pthread_mutex_unlock(&list->lock)
+        ;
+    }
+}
+
+psListElem* listGetIterator(psList* list)
+{
+    if (list == NULL) {
+        return NULL;
+    }
+
+    if (list->iter == ITER_INIT_HEAD) {
+        return list->head;
+    } else if (list->iter == ITER_INIT_TAIL) {
+        return list->tail;
+    } else {
+        return list->iter;
+    }
+}
+
+int listGetIteratorIndex(psList* list)
+{
+    if (list->iter == ITER_INIT_HEAD) {
+        return 0;
+    } else if (list->iter == ITER_INIT_TAIL) {
+        return list->size - 1;
+    } else {
+        return list->iterIndex;
+    }
+}
+
+void *psListGet(psList* list, int location)
+{
+    psListElem* element;
+
+    psListSetIterator(list, location);
+    element = listGetIterator(list);
+
+    if (element == NULL) {
+        return NULL;
+    } else {
+        return element->data;
+    }
+}
+
+/*
+ * and now return the previous/next element of the list
+ */
+void *psListGetNext(psList* list)
+{
+    return psListGet(list, PS_LIST_NEXT);
+}
+
+void *psListGetPrevious(psList* list)
+{
+    return psListGet(list, PS_LIST_PREVIOUS);
+}
+
+void *psListGetCurrent(psList* list)
+{
+    return psListGet(list, PS_LIST_CURRENT);
+}
+
+/*
+ * Convert a psList to/from a psVoidPtrArray
+ */
+psArray* psListToArray(psList* restrict list)
+{
+    psListElem* ptr;
+    unsigned int n;
+    psArray* restrict arr;
+
+    if (list == NULL) {
+        return NULL;
+    }
+
+    if (list->size > 0) {
+        arr = psArrayAlloc(list->size);
+    } else {
+        arr = psArrayAlloc(1);
+    }
+
+    arr->n = list->size;
+
+    ptr = list->head;
+    n = list->size;
+    for (int i = 0; i < n; i++) {
+        arr->data[i] = psMemIncrRefCounter(ptr->data);
+        ptr = ptr->next;
+    }
+
+    return arr;
+}
+
+psList* psArrayToList(psArray* arr)
+{
+    unsigned int n;
+    psList* list;               // list of elements
+
+    if (arr == NULL) {
+        return NULL;
+    }
+
+    list = psListAlloc(NULL);
+    n = arr->n;
+    for (int i = 0; i < n; i++) {
+        psListAdd(list, PS_LIST_TAIL, arr->data[i]);
+    }
+
+    return list;
+}
+
+psList* psListSort(psList* list, psComparePtrFcn compare)
+{
+    psArray* arr;
+
+    if (list == NULL) {
+        return NULL;
+    }
+    // convert to indexable vector for use by qsort.
+    arr = psListToArray(list);
+    psFree(list);
+
+    arr = psArraySort(arr, compare);
+
+    // convert back to linked list
+    list = psArrayToList(arr);
+    psFree(arr);
+
+    return list;
+}
Index: /branches/rel3/psLib/src/collections/psList.h
===================================================================
--- /branches/rel3/psLib/src/collections/psList.h	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psList.h	(revision 2163)
@@ -0,0 +1,192 @@
+#if !defined(PS_LIST_H)
+#define PS_LIST_H
+
+/** @file psList.h
+ *  @brief Support for doubly linked lists
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @ingroup LinkedList
+ *
+ *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-09 02:23:27 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <pthread.h>                   // we need a mutex to make this stuff thread safe.
+#include <stdbool.h>                   // we use the bool type.
+
+#include "psCompare.h"
+#include "psArray.h"
+
+/** @addtogroup LinkedList
+ *  @{
+ */
+
+/** Special values of index into list
+ *
+ *  This list of possible list position values should be contiguous non-positive values ending with
+ *  PS_LIST_UNKNOWN.  Any value less-than-or-equal-to PS_LIST_UNKNOWN is considered a undefined position.
+ *
+ */
+enum {
+    PS_LIST_HEAD = 0,                  ///< at head
+    PS_LIST_TAIL = -1,                 ///< at tail
+    PS_LIST_PREVIOUS = -2,             ///< previous element
+    PS_LIST_CURRENT = -3,              ///< current element
+    PS_LIST_NEXT = -4,                 ///< next element
+    PS_LIST_UNKNOWN = -5               ///< unknown position (should be last in enum list)
+};
+
+/** Doubly-linked list element */
+typedef struct psListElem
+{
+    struct psListElem* prev;           ///< previous link in list
+    struct psListElem* next;           ///< next link in list
+    void *data;                        ///< real data item
+}
+psListElem;
+
+/** The psList Linked list structure.  User should not allocate this struct
+ *  directly; rather the psListAlloc should be used.
+ *
+ *  @see psListAlloc, psListFree
+ */
+typedef struct
+{
+    unsigned int size;                 ///< number of elements on list
+    psListElem* head;                  ///< first element on list (may be NULL)
+    psListElem* tail;                  ///< last element on list (may be NULL)
+    psListElem* iter;                  ///< iteration cursor
+    unsigned int iterIndex;            ///< the numeric position of the iteration cursor in the list
+    pthread_mutex_t lock;              ///< mutex to lock a node during changes
+}
+psList;
+
+/** Creates a psList linked list object.
+ *
+ *  @return psList* A new psList object.
+ */
+psList* psListAlloc(
+    void *data
+    ///< initial data item; may be NULL if no an empty psList is desired
+)
+;
+
+/** Adds an element to a psList at position given.
+ *
+ *  @return psList* The psList with added data item.  If list parameter is
+ *                      NULL, the return value will also be NULL.
+ */
+bool psListAdd(
+    psList* restrict list,             ///< list to add to (if NULL, nothing is done)
+    int location,                      ///< index, PS_LIST_HEAD, PS_LIST_TAIL, or numbered location.
+    void *data                         ///< data item to add.  If NULL, list is not modified.
+);
+
+/** Remove an item from a list.  If location parameter is PS_LIST_UNKNOWN,
+ *
+ *  @return bool        TRUE if element is successfully removed, otherwise FALSE.
+ */
+bool psListRemove(
+    psList* restrict list,
+    ///< list to remove element from
+    int location,
+    ///< index of item, or PS_LIST_UNKNOWN, PS_LIST_NEXT, PS_LIST_PREV, or numbered location.
+    void *data
+    ///< if location is PS_LIST_UNKNOWN, data item to find and remove, otherwise this is ignored.
+);
+
+/** Retrieve an item from a list.
+ *
+ *  @return void*       the item corresponding to the location parameter.  If
+ *                      location is invalid (e.g., a numbered index greater
+ *                      than the list size or if the list is empty), a
+ *                      NULL is returned.
+ */
+void *psListGet(
+    psList* restrict list,             ///< list to retrieve element from
+    int location                       ///< index number, or PS_LIST_NEXT, PS_LIST_PREV, PS_LIST_UNKNOWN
+);
+
+/** Set the iterator of the list to a given position.  If location is invalid the
+ *  iterator position is not changed.
+ *
+ */
+void psListSetIterator(
+    psList* restrict list,             ///< list to retrieve element from
+    int location                       ///< index number, PS_LIST_HEAD, or PS_LIST_TAIL
+);
+
+/** Get next element relative to the iterator.  This also moves the iterator to
+ *  the next list position.
+ *
+ *  @return void*       the data item next on the list or NULL if the iterator
+ *                      is already pointing to the last element or the list
+ *                      parameter was NULL.
+ */
+void *psListGetNext(
+    psList* restrict list              ///< list to retrieve element from
+);
+
+/** Get current element according to the psList's iterator cursor.  This does
+ *  not move the iterator location.
+ *
+ *  @return void*       the data item cooresponding to current iterator
+ *                      cursor position of the list, or NULL if either the
+ *                      iterator is not valid or list parameter was NULL.
+ */
+void *psListGetCurrent(
+    psList* restrict list              ///< list to retrieve element from
+);
+
+/** Get previous element relative to list's iterator. This also moves the
+ *  iterator to the previous list position.
+ *
+ *  @return void*       the data item previous on the list or NULL if the iterator
+ *                      is already pointing to the first element or the list
+ *                      parameter was NULL.
+ */
+void *psListGetPrevious(
+    psList* restrict list              ///< list to retrieve element from
+);
+
+/** Convert a linked list to an array
+ *
+ *  @return psArray* A new psArray populated with elements from the list,
+ *                      or NULL if the given dlist parameter is NULL.
+ */
+psArray* psListToArray(
+    psList* dlist                      ///< List to convert
+);
+
+/** Convert array to a doubly-linked list
+ *
+ *  @return psList* A new psList populated with elements formt the psArray,
+ *                      or NULL is the given arr parameter is NULL.
+ */
+psList* psArrayToList(
+    psArray* arr                       ///< vector to convert
+);
+
+/** Sort a list via a comparison function.
+ *
+ *  The comparison function must return an integer less than, equal to, or 
+ *  greater than zero if the first argument is considered to be respectively 
+ *  less than, equal to, or greater than the second. 
+ *
+ *  If two members compare as equal, their order in the sorted array is 
+ *  undefined.
+ *
+ *  @return psList*     Sorted list.
+ */
+psList* psListSort(
+    psList* list,                      ///< the list to sort
+    psComparePtrFcn compare            ///< the comparison function
+);
+
+/// @} End of DataGroup Functions
+
+#endif
Index: /branches/rel3/psLib/src/collections/psMetadata.c
===================================================================
--- /branches/rel3/psLib/src/collections/psMetadata.c	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psMetadata.c	(revision 2163)
@@ -0,0 +1,589 @@
+
+/** @file  psMetadata.c
+*
+*
+*  @brief Contains metadata structures, enumerations and functions prototypes.
+*
+*  This file defines metadata item, metadata type, metadata flags, metadata containers, and function
+*  prototypes necessary creating psLib metadata APIs
+*
+*  @ingroup Metadata
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.34 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-09 03:05:53 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include<stdio.h>
+#include<stdarg.h>
+#include<string.h>
+
+#include "fitsio.h"
+#include "psType.h"
+#include "psMemory.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psList.h"
+#include "psHash.h"
+#include "psVector.h"
+#include "psMetadata.h"
+#include "psString.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Maximum size of a string */
+#define MAX_STRING_LENGTH 1024
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+static int metadataId = 0;
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+static void metadataItemFree(psMetadataItem* metadataItem)
+{
+    psMetadataType type;
+
+    type = metadataItem->type;
+
+    if (metadataItem == NULL) {
+        return;
+    }
+
+    psFree(metadataItem->name);
+    psFree(metadataItem->comment);
+    psFree(metadataItem->items);
+
+    if (type == PS_META_STR || type == PS_META_VEC || type == PS_META_IMG || type == PS_META_JPEG ||
+            type == PS_META_PNG || type == PS_META_ASTROM || type == PS_META_UNKNOWN) {
+        psFree(metadataItem->data.V);
+    }
+}
+
+static void metadataFree(psMetadata* metadata)
+{
+    if (metadata == NULL) {
+        return;
+    }
+    psFree(metadata->list);
+    psFree(metadata->table);
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+psMetadataItem* psMetadataItemAlloc(const char *name, psMetadataType type, const char *comment, ...)
+{
+    va_list argPtr;
+    psMetadataItem* metadataItem = NULL;
+
+    // Get the variable list parameters to pass to allocation function
+    va_start(argPtr, comment);
+
+    // Call metadata item allocation
+    metadataItem = psMetadataItemAllocV(name, type, comment, argPtr);
+
+    // Clean up stack after variable arguement has been used
+    va_end(argPtr);
+
+    return metadataItem;
+}
+
+psMetadataItem* psMetadataItemAllocV(const char *name, psMetadataType type, const char *comment,
+                                     va_list argPtr)
+{
+    psVector *vecIn = NULL;
+    psVector *vecOut = NULL;
+    psMetadataItem* metadataItem = NULL;
+
+
+    if (name == NULL) {
+        psError(__func__, "Null value for name not allowed");
+        return NULL;
+    }
+    // Allocate metadata item
+    metadataItem = (psMetadataItem* ) psAlloc(sizeof(psMetadataItem));
+
+    // Set deallocator
+    p_psMemSetDeallocator(metadataItem, (psFreeFcn) metadataItemFree);
+
+    // Allocate and set metadata item comment
+    metadataItem->comment = (char *)psAlloc(sizeof(char) * MAX_STRING_LENGTH);
+    if (comment == NULL) {
+        // Per SDRS, null isn't allowed, must use "" instead
+        strncpy(metadataItem->comment, "", MAX_STRING_LENGTH);
+    } else {
+        strncpy(metadataItem->comment, comment, MAX_STRING_LENGTH);
+    }
+
+    // Set metadata item unique id
+    *(int *)(&metadataItem->id) = ++metadataId;
+
+    // Set metadata item type
+    metadataItem->type = type;
+
+    // Set metadata item value
+    switch (type) {
+    case PS_META_ITEM_SET:
+        metadataItem->data.V = NULL;
+        break;
+    case PS_META_BOOL:
+        metadataItem->data.B = (bool)va_arg(argPtr, int);
+        break;
+    case PS_META_S32:
+        metadataItem->data.S32 = (psS32)va_arg(argPtr, psS32);
+        break;
+    case PS_META_F32:
+        metadataItem->data.F32 = (psF32)va_arg(argPtr, psF64);
+        break;
+    case PS_META_F64:
+        metadataItem->data.F64 = va_arg(argPtr, psF64);
+        break;
+    case PS_META_STR:
+        metadataItem->data.V = psStringNCopy(va_arg(argPtr, char *), MAX_STRING_LENGTH);
+        break;
+    case PS_META_VEC:
+        vecIn = (psVector*)va_arg(argPtr, psVector*);
+        vecOut = psVectorAlloc(vecIn->nalloc, vecIn->type.type);
+        memcpy(vecOut->data.V, vecIn->data.V, vecIn->nalloc*PSELEMTYPE_SIZEOF(vecIn->type.type));
+        metadataItem->data.V = vecOut;
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+    default:
+        psError(__func__, "Invalid psMetadataType: %d", type);
+    }
+
+    // Allocate and set metadata item name
+    metadataItem->name = (char *)psAlloc(sizeof(char) * MAX_STRING_LENGTH);
+    vsprintf(metadataItem->name, name, argPtr);
+
+    // Allocate metadata items with same name.
+    metadataItem->items = psListAlloc(NULL);
+
+    return metadataItem;
+}
+
+psMetadata* psMetadataAlloc(void)
+{
+    psList* list = NULL;
+    psHash* table = NULL;
+    psMetadata* metadata = NULL;
+
+    // Allocate metadata
+    metadata = (psMetadata* ) psAlloc(sizeof(psMetadata));
+    // Set deallocator
+    p_psMemSetDeallocator(metadata, (psFreeFcn) metadataFree);
+
+    // Allocate metadata's internal containers
+    list = (psList* ) psListAlloc(NULL);
+
+    table = (psHash* ) psHashAlloc(10);
+
+    metadata->list = list;
+    metadata->table = table;
+
+    return metadata;
+}
+
+bool psMetadataAddItem( psMetadata *restrict md, psMetadataItem *restrict metadataItem, int location )
+{
+    char * key = NULL;
+    psHash *mdTable = NULL;
+    psList *mdList = NULL;
+    psMetadataItem *existingEntry = NULL;
+    psMetadataItem *newFolderEntry = NULL;
+    psMetadataType newType = PS_META_ITEM_SET;
+
+    if(md == NULL) {
+        psError( __func__, "Null metadata collection not allowed" );
+        return false;
+    }
+
+    if(metadataItem == NULL) {
+        psError( __func__, "Null metadata item not allowed" );
+        return false;
+    }
+
+    newType = metadataItem->type;
+
+    mdTable = md->table;
+    if(mdTable == NULL) {
+        psError( __func__, "Null metadata table not allowed" );
+        return false;
+    }
+
+    mdList = md->list;
+    if(mdList == NULL) {
+        psError( __func__, "Null metadata list not allowed");
+        return false;
+    }
+
+    key = metadataItem->name;
+    if(key == NULL) {
+        psError(__func__, "Null key item not allowed");
+        return false;
+    }
+
+    // See if key is already in table
+    existingEntry = (psMetadataItem*)psHashLookup(mdTable, key);
+    if(existingEntry != NULL) {
+
+        if(existingEntry->type == PS_META_ITEM_SET) {
+
+            // Add leaf node to existing folder node
+            if(!psListAdd(existingEntry->items, PS_LIST_TAIL, metadataItem)) {
+                psError( __func__, "Couldn't add metadata item to items list. Name: %s",
+                         metadataItem->name );
+                return false;
+            }
+        } else if(existingEntry->type != PS_META_ITEM_SET && newType!= PS_META_ITEM_SET) {
+
+            // Leaf node replaces another leaf. Make new folder node and add leaves.
+            newFolderEntry = psMetadataItemAlloc(key, PS_META_ITEM_SET, NULL, NULL);
+
+            if(!psListAdd(newFolderEntry->items, PS_LIST_TAIL, existingEntry)) {
+                psError( __func__, "Couldn't add metadata item to items list. Name: %s", key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psListAdd(newFolderEntry->items, PS_LIST_TAIL, metadataItem)) {
+                psError( __func__, "Couldn't add metadata item to items list. Name: %s", key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psHashRemove(mdTable, key)) {
+                psError( __func__, "Couldn't remove metadata item from metadata table. Name: %s", key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psHashAdd(mdTable, key, newFolderEntry)) {
+                psError( __func__, "Couldn't add metadata item to metadata table. Name: %s", key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            // Remove local reference to new folder node
+            psMemDecrRefCounter(newFolderEntry);
+        } else {
+
+            // Folder node replaces leaf or folder node - Put old node into new folder and remove from table
+            if(!psListAdd(metadataItem->items, PS_LIST_TAIL, existingEntry)) {
+                psError( __func__, "Couldn't add metadata item to items list. Name: %s", key);
+                return false;
+            }
+
+            if(!psHashRemove(mdTable, key)) {
+                psError( __func__, "Couldn't remove metadata item from metadata table. Name: %s", key);
+                return false;
+            }
+
+            if(!psHashAdd(mdTable, key, metadataItem)) {
+                psError( __func__, "Couldn't add metadata item to metadata table. Name: %s", key);
+                return false;
+            }
+        }
+    } else {
+
+        // Node doesn't exist - Add new metadata item to metadata collection's hash
+        if(!psHashAdd(mdTable, key, metadataItem)) {
+            psError( __func__, "Couldn't add metadata item to metadata table. Name: %s", key);
+            return false;
+        }
+    }
+
+    // Add items to metadata collection's list, even if they have the same metadata item names. Folder nodes
+    // (PS_META_ITEM_SET metadata items) are not added, since the metadata list is flat.
+    if(metadataItem->type != PS_META_ITEM_SET) {
+        if(!psListAdd(mdList, location, metadataItem)) {
+            psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s",
+                     metadataItem->name );
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool psMetadataAdd(psMetadata* restrict md, int where, const char *name, psMetadataType type,
+                   const char *comment, ...)
+{
+    va_list argPtr;
+    psMetadataItem* metadataItem = NULL;
+
+    va_start(argPtr, comment);
+    metadataItem = psMetadataItemAllocV(name, type, comment, argPtr);
+    va_end(argPtr);
+
+    if (!psMetadataAddItem(md, metadataItem, where)) {
+        psError(__func__, "Couldn't add metadata item to metadata collection list. Name: %s",
+                metadataItem->name);
+        psFree(metadataItem);
+        return false;
+    }
+    // Decrement reference count, since the metadata item is now in metadata collection and no longer needed
+    psMemDecrRefCounter(metadataItem);
+
+    return true;
+}
+
+bool psMetadataRemove(psMetadata* restrict md, int where, const char *restrict key)
+{
+    int numChildren = 0;
+    psList* mdList = NULL;
+    psHash* mdTable = NULL;
+    psMetadataItem* entry = NULL;
+    psMetadataItem* entryChild = NULL;
+
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return false;
+    }
+
+    mdList = md->list;
+    if (mdList == NULL) {
+        psError(__func__, "Null metadata list not allowed");
+        return false;
+    }
+
+    mdTable = md->table;
+    if (mdTable == NULL) {
+        psError(__func__, "Null metadata table not allowed");
+        return false;
+    }
+    // Select removal by key or index
+    if (key != NULL) {
+
+        // Remove by key name
+        entry = (psMetadataItem* ) psHashLookup(mdTable, key);
+        if (entry == NULL) {
+            psError(__func__, "Couldn't find metadata item. Name: %s", key);
+            return false;
+        }
+
+        numChildren = entry->items->size;
+        if (entry->type == PS_META_ITEM_SET && numChildren > 0) {
+
+            // Table entry has children. Entry and children must be removed from metadata collection's list
+            psListSetIterator(entry->items, PS_LIST_HEAD);
+            entryChild = psListGetCurrent(entry->items);
+            while (entryChild != NULL) {
+                if (!psListRemove(mdList, PS_LIST_UNKNOWN, entryChild)) {
+                    psError(__func__, "Couldn't remove metadata item from list. Name: %s", key);
+                    return false;
+                }
+                entryChild = psListGetNext(entry->items);
+            }
+        } else {
+
+            // Table entry has no children. Remove entry from metadata collection's list
+            if (!psListRemove(mdList, PS_LIST_UNKNOWN, entry)) {
+                psError(__func__, "Couldn't remove metadata item from list. Name: %s", key);
+                return false;
+            }
+        }
+        // Remove entry from metadata collection's table
+        if (!psHashRemove(mdTable, key)) {
+            psError(__func__, "Couldn't remove metadata item from table. Name: %s", key);
+            return false;
+        }
+    } else {
+
+        // Remove by index
+        entry = psListGet(mdList, where);
+        if (entry == NULL) {
+            psError(__func__, "Couldn't find metadata item in list. Index: %d", where);
+            return false;
+        }
+
+        key = entry->name;
+        if (key == NULL) {
+            psError(__func__, "Null key name not allowed. Index: %d", where);
+            return false;
+        }
+        // Use recursive remove, now that key is known
+        psMetadataRemove(md, PS_LIST_UNKNOWN, key);
+    }
+
+    return true;
+}
+
+psMetadataItem* psMetadataLookup(psMetadata* restrict md, const char *restrict key)
+{
+    psHash* mdTable = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return NULL;
+    }
+
+    mdTable = md->table;
+    if (mdTable == NULL) {
+        psError(__func__, "Null metadata table not allowed");
+        return NULL;
+    }
+
+    if (key == NULL) {
+        psError(__func__, "Null key name not allowed");
+        return NULL;
+    }
+
+    entry = (psMetadataItem* ) psHashLookup(mdTable, key);
+    if (entry == NULL) {
+        return NULL;
+    }
+
+    return entry;
+}
+
+psMetadataItem* psMetadataGet(psMetadata* restrict md, int where)
+{
+    psList* mdList = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return NULL;
+    }
+
+    mdList = md->list;
+    if (mdList == NULL) {
+        psError(__func__, "Null metadata list not allowed");
+        return NULL;
+    }
+
+    entry = (psMetadataItem* ) psListGet(mdList, where);
+    if (entry == NULL) {
+        psError(__func__, "Couldn't find metadata item with given index. Index: %d", where);
+        return NULL;
+    }
+
+    return entry;
+}
+
+bool psMetadataSetIterator(psMetadata* restrict md, int where)
+{
+    psList* mdList = NULL;
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return false;
+    }
+
+    mdList = md->list;
+    if (mdList == NULL) {
+        psError(__func__, "Null metadata list not allowed");
+        return false;
+    }
+
+    psListSetIterator(mdList, where);
+
+    return true;
+}
+
+psMetadataItem* psMetadataGetNext(psMetadata* restrict md, const char *restrict match, int which)
+{
+    psList* mdList = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return NULL;
+    }
+
+    mdList = md->list;
+    if (mdList == NULL) {
+        psError(__func__, "Null metadata list not allowed");
+        return NULL;
+    }
+
+    psListSetIterator(mdList, which);
+    entry = psListGetCurrent(mdList);
+    while (entry != NULL) {
+        if(match != NULL) {
+            if (!strncmp(match, entry->name, strlen(match))) {
+
+                // Match found
+                return entry;
+            }
+            entry = psListGetNext(mdList);
+        } else {
+            entry = psListGetNext(mdList);
+            break;
+        }
+    }
+
+    return entry;
+}
+
+psMetadataItem* psMetadataGetPrevious(psMetadata* restrict md, const char *restrict match, int which)
+{
+    psList* mdList = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return NULL;
+    }
+
+    mdList = md->list;
+    if (mdList == NULL) {
+        psError(__func__, "Null metadata list not allowed");
+        return NULL;
+    }
+
+    psListSetIterator(mdList, which);
+    entry = psListGetCurrent(mdList);
+    while (entry != NULL) {
+        if(match != NULL) {
+            if (!strncmp(match, entry->name, strlen(match))) {
+
+                // Match found
+                return entry;
+            }
+            entry = psListGetPrevious(mdList);
+        } else {
+            entry = psListGetPrevious(mdList);
+            break;
+        }
+    }
+
+    return entry;
+}
Index: /branches/rel3/psLib/src/collections/psMetadata.h
===================================================================
--- /branches/rel3/psLib/src/collections/psMetadata.h	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psMetadata.h	(revision 2163)
@@ -0,0 +1,247 @@
+
+/** @file  psMetadata.h
+*
+*  @brief Contains metadata struuctures, enumerations and functions prototypes
+*
+*  This file defines metadata item, metadata type, metadata flags, metadata containers, and function
+*  prototypes necessary creating psLib metadata APIs
+*
+*  @ingroup Metadata
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.23 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-06 01:06:27 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#ifndef PS_METADATA_H
+#define PS_METADATA_H
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "psHash.h"
+#include "psList.h"
+
+/// @addtogroup Metadata
+/// @{
+
+/** Metadata item type.
+ *
+ * Enumeration for maintaining metadata item types.
+ */
+typedef enum {
+    PS_META_ITEM_SET = 0,              ///< Null. Metadata is in psMetadataItem.items
+    PS_META_BOOL,                      ///< Boolean data.
+    PS_META_S32,                       ///< Signed 32-bit integer data.
+    PS_META_F32,                       ///< Single-precision float data.
+    PS_META_F64,                       ///< Double-precision float data.
+    PS_META_STR,                       ///< String data (Stored in as void *).
+    PS_META_VEC,                       ///< Vector data (Stored in as void *).
+    PS_META_IMG,                       ///< Image data (Stored in as void *).
+    PS_META_JPEG,                      ///< JPEG data (Stored in as void *).
+    PS_META_PNG,                       ///< PNG data (Stored in as void *).
+    PS_META_ASTROM,                    ///< Astrometric coefficients (Stored in as void *).
+    PS_META_UNKNOWN,                   ///< Other data (Stored in as void *).
+    PS_META_NTYPE                      ///< Number of types. Must be last.
+} psMetadataType;
+
+/** Metadata item data structure.
+ *
+ * Struct for maintaining metadata items of varying types. It also contains
+ * information about the item name, flags, comments, and other items with the same name.
+ */
+typedef struct psMetadataItem
+{
+    const int id;                      ///< Unique ID for metadata item.
+    char *restrict name;               ///< Name of metadata item.
+    psMetadataType type;               ///< Type of metadata item.
+    union {
+        bool B;                        ///< boolean data
+        psS32 S32;                     ///< Signed 32-bit integer data.
+        psF32 F32;                     ///< Single-precision float data.
+        psF64 F64;                     ///< Double-precision float data.
+        psPTR V;                       ///< Pointer to other type of data.
+    } data;                            ///< Union for data types.
+    char *comment;                     ///< Optional comment ("", not NULL).
+    psList* restrict items;            ///< List of psMetadataItems with same name.
+}
+psMetadataItem;
+
+/** Metadata data structure.
+ *
+ *  Struct for holding metadata items. Metadata items are held in two
+ *  containers. The first employs a doubly-linked list to preserve the order
+ *  of the metadata. The second container employs a hash table which
+ *  allows fast lookup when given a metadata keyword.
+ */
+typedef struct psMetadata
+{
+    psList* restrict list;             ///< the metadata in linked-list
+    psHash* restrict table;            ///< the metadata in a hash table
+}
+psMetadata;
+
+/** Create a metadata item.
+ *
+ *  Returns a fill psMetadataItem ready for insertion into the psMetadata
+ *  struct. The name argument specifies the name to use for this item, and
+ *  may include sprintf formatting codes. The format entry specifies both
+ *  the metadata type and optional flags and is created by bit-wise or of the
+ *  appropriate type and flag. The comment argument is a fixed string used to
+ *  comment the metadata item. The arguments to the name formatting codes and
+ *  the metadata itself are passed as arguments following the comment string.
+ *  The data must be a pointer for any of the elements stored in data.void.
+ *  The argument list must be interpreted appropriately by the va_list
+ *  operators in the function specified size and type.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataItemAlloc(
+    const char *name,                  ///< Name of metadata item.
+    psMetadataType type,               ///< Type of metadata item.
+    const char *comment,               ///< Comment for metadata item.
+    ...                                ///< Arguments for name formatting and metadata item data.
+);
+
+/** Create a metadata item with va_list.
+ *
+ *  Returns a fill psMetadataItem ready for insertion into the psMetadata
+ *  struct. The name argument specifies the name to use for this item, and
+ *  may include sprintf formatting codes. The format entry specifies both
+ *  the metadata type and optional flags and is created by bit-wise or of the
+ *  appropriate type and flag. The comment argument is a fixed string used to
+ *  comment the metadata item. The arguments to the name formatting codes and
+ *  the metadata itself are passed as arguments following the comment string.
+ *  The data must be a pointer for any of the elements stored in data.void.
+ *  The argument list must be interpreted appropriately by the va_list
+ *  operators in the function specified size and type.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataItemAllocV(
+    const char *name,                  ///< Name of metadata item.
+    psMetadataType type,               ///< Type of metadata item.
+    const char *comment,               ///< Comment for metadata item.
+    va_list list                       ///< Arguments for name formatting and metadata item data.
+);
+
+/** Create a metadata collection.
+ *
+ *  Returns an empty metadata container with fully allocated internal metadata
+ *  containers.
+ *
+ *  @return psMetadata* : Pointer metadata.
+ */
+psMetadata* psMetadataAlloc(void);
+
+/** Add existing metadata item to metadata collection.
+ *
+ *  Add a metadata item that has already been created to the metadata
+ *  collection.
+ *
+ *  @return bool: True for success, false for failure.
+ */
+bool psMetadataAddItem(
+    psMetadata* restrict md,           ///< Metadata collection to insert metadat item.
+    psMetadataItem* restrict item,     ///< Metadata item to be added.
+    int location                       ///< Location to be added.
+);
+
+/** Create and add a metadata item to metadata collection.
+ *
+ * Creates a new metadata item add to the metadata collection.
+ *
+ * @return bool: True for success, false for failure.
+ */
+bool psMetadataAdd(
+    psMetadata* restrict md,           ///< Metadata collection to insert metadat item.
+    int where,                         ///< Location to be added.
+    const char *name,                  ///< Name of metadata item.
+    psMetadataType type,               ///< Type of metadata item.
+    const char *comment,               ///< Comment for metadata item.
+    ...                                ///< Arguments for name formatting and metadata item data.
+);
+
+/** Remove an item from metadata collection.
+ *
+ *  Items may be removed from metadata by specifing a key or location. If the
+ *  name is null, the where argument is used instead. If name is not null,
+ *  where is set to PS_LIST_UNKNOWN. If the item is found, it is removed from
+ *  the metadata and true is returned.  If the key is not unique, then all
+ *  items corresponding to it are removed.
+ *
+ * @return bool: True for success, false for failure.
+ */
+bool psMetadataRemove(
+    psMetadata* restrict md,           ///< Metadata collection to insert metadat item.
+    int where,                         ///< Location to be removed.
+    const char *restrict key           ///< Name of metadata key.
+);
+
+/** Find an item in the metadata collection based on key name.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the first item is returned. If the item is not found, null is
+ *  returned.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataLookup(
+    psMetadata* restrict md,           ///< Metadata collection to insert metadata item.
+    const char *restrict key           ///< Name of metadata key.
+);
+
+/** Find an item in the metadata collection based on list index.
+ *
+ *  Items may be found in the metadata by their entry position in the list
+ *  container.
+ *
+ *  @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataGet(
+    psMetadata* restrict md,           ///< Metadata collection to insert metadat item.
+    int where                          ///< Location to be retrieved.
+);
+
+/** Set or reset metadata iterator.
+ *
+ *  Metadata may be iterated by setting or resetting an iterator to a location
+ *  in the metadata list.
+ *
+ * @return void: void.
+ */
+bool psMetadataSetIterator(
+    psMetadata* restrict md,           ///< Metadata collection to iterate.
+    int where                          ///< Location of iterator.
+);
+
+/** Get next metadata item.
+ *
+ * Get next metadata item in iterator list.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataGetNext(
+    psMetadata* restrict md,           ///< Metadata collection to iterate.
+    const char *restrict match,        ///< Beginning of key name.
+    int which                          ///< Iterator to be used.
+);
+
+/** Get previous metadata item.
+ *
+ * Get previous metadata item in iterator list.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataGetPrevious(
+    psMetadata* restrict md,           ///< Metadata collection to iterate.
+    const char *restrict match,        ///< Beginning of key name.
+    int which                          ///< Iterator to be used.
+);
+
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/collections/psMetadataIO.c
===================================================================
--- /branches/rel3/psLib/src/collections/psMetadataIO.c	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psMetadataIO.c	(revision 2163)
@@ -0,0 +1,662 @@
+/** @file  psMetadataIO.c
+*
+*  @brief Contains metadata input/output functions.
+*
+*  This file defines functions to read and write metadata to/from an external file.
+*
+*  @ingroup Metadata
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-08 00:43:12 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include <fitsio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "psAbort.h"
+#include "psType.h"
+#include "psMemory.h"
+#include "psError.h"
+#include "psString.h"
+#include "psList.h"
+#include "psHash.h"
+#include "psVector.h"
+#include "psMetadata.h"
+#include "psMetadataIO.h"
+
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Check for FITS errors */
+#define FITS_ERROR(STRING,PS_ERROR) \
+fits_get_errstatus(status, fitsErr); \
+psError(__func__, STRING, PS_ERROR, fitsErr); \
+status = 0; \
+fits_close_file(fd, &status); \
+if(status){ \
+    fits_get_errstatus(status, fitsErr); \
+    psError(__func__, "Couldn't close FITS file. FITS error: %s", fitsErr); \
+} \
+status = 0; \
+psFree(output); \
+return NULL;
+
+/** Free and null temporary variables used by config file parser */
+#define CLEAR_TEMPS()                                                                                        \
+if(strName) {                                                                                            \
+    psFree(strName);                                                                                     \
+    strName = NULL;                                                                                      \
+}                                                                                                        \
+if(strType) {                                                                                            \
+    psFree(strType);                                                                                     \
+    strType = NULL;                                                                                      \
+}                                                                                                        \
+if(strValue) {                                                                                           \
+    psFree(strValue);                                                                                    \
+    strValue = NULL;                                                                                     \
+}                                                                                                        \
+if(strComment) {                                                                                         \
+    psFree(strComment);                                                                                  \
+    strComment = NULL;                                                                                   \
+}                                                                                                        \
+if(tempVec) {                                                                                            \
+    psFree(tempVec);                                                                                     \
+    tempVec = NULL;                                                                                      \
+}
+
+/** Maximum size of a FITS line */
+#define FITS_LINE_SIZE 80
+
+/** Maximum size of a string */
+#define MAX_STRING_LENGTH 256
+
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+
+/** Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string
+ *  must be null terminated. */
+bool ignoreLine(char *inString)
+{
+    while(*inString!='\0' && *inString!='#') {
+        if(!isspace(*inString)) {
+            return false;
+        }
+        inString++;
+    }
+
+    return true;
+}
+
+
+/** Removes leading and trailing whitespace and # characters from a string. The cleaned string is a new null
+ *  terminated copy of the original input string. */
+char *cleanString(char *inString, int sLen)
+{
+    char *ptrB = NULL;
+    char *ptrE = NULL;
+    char *cleaned = NULL;
+
+
+    ptrB = inString;
+
+    /* Skip over leading # or whitespace */
+    while (isspace(*ptrB) || *ptrB=='#') {
+        ptrB++;
+    }
+
+    /* Skip over trailing whitespace, null terminators, and # characters */
+    ptrE = inString + sLen;
+    while(isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') {
+        ptrE--;
+    }
+
+    // Length, sLen, does not include '\0'
+    sLen = ptrE - ptrB + 1;
+
+    // Adds '\0' to end of string and +1 to sLen
+    cleaned = psStringNCopy(ptrB, sLen);
+
+    return cleaned;
+}
+
+/** Count repeat occurances of a single character within a line. The input string must be null terminated. */
+int repeatedChars(char *inString, char ch)
+{
+    int count = 0;
+
+
+    while(*inString!='\0') {
+        if(*inString == ch) {
+            count++;
+        }
+        inString++;
+    }
+
+    return count;
+}
+
+/** Returns cleaned token based on delimiter, but not including delimiter. Also changes the pointer location
+ * the beginning of the string. Tokens are newly allocated null terminated strings. */
+char* getToken(char **inString, char *delimiter, int *status)
+{
+    char *cleanToken = NULL;
+    int sLen = 0;
+
+
+    // Skip over leading whitespace
+    while(isspace(**inString)) {
+        (*inString)++;
+    }
+
+    // Length of token, not including delimiter
+    sLen = strcspn(*inString, delimiter);
+    if(sLen) {
+
+        // Create new, cleaned, and null terminated token
+        cleanToken = cleanString(*inString, sLen);
+
+        // Move to end of token
+        (*inString) += sLen;
+    } else if(**inString!='\0' && sLen==0) {
+        *status = 1;
+    }
+
+    return cleanToken;
+}
+
+/** Returns single parsed value as a double precision number. The input string must be cleaned and null
+ * terminated. */
+double parseValue(char *inString, int *status)
+{
+    char *end = NULL;
+    double value = 0.0;
+
+
+    value = strtod(inString, &end);
+    if(*end != '\0') {
+        *status = 1;
+    } else if(inString==end) {
+        *status = 1;
+    }
+
+    return value;
+}
+
+/** Returns true or false. 'T', 't', '1', 'F', 'f', and '0' are acceptable, parsable variations. */
+bool parseBool(char *inString, int *status)
+{
+    bool value = false;
+
+
+    if(*inString=='T' || *inString=='t' || *inString=='1') {
+        value = true;
+    } else if(*inString=='F' || *inString=='f' || *inString=='0') {
+        value = false;
+    } else {
+        *status = 1;
+    }
+
+    return value;
+}
+
+/** Returns parsed vector filled with with data. The input string must be null terminated. */
+psVector* parseVector(char *inString, psElemType elemType, int *status)
+{
+    char *end = NULL;
+    char *saveValue = NULL;
+    int i = 0;
+    int numValues = 0;
+    double value = 0.0;
+    psVector *vec = NULL;
+
+
+    // Cycle through string and count entries
+    saveValue = inString;
+    while(*inString!='\0') {
+        strtod(inString, &end);
+        if(inString==end) {
+            *status = 1;
+            return NULL;
+        }
+        while(*end==' ' || *end==',') { // Commas or spaces may be used as delimiters for vector values
+            end++;
+        }
+        inString=end;
+        numValues++;
+    }
+
+    // Cycle through string and convert string values to values
+    if(numValues) {
+        inString = saveValue;
+        end = NULL;
+        vec = psVectorAlloc(numValues, elemType);
+
+        while(*inString!='\0') {
+            value = strtod(inString, &end);
+            if(inString==end) {
+                *status = 1;
+                return vec;
+            }
+            switch(elemType) {
+            case PS_TYPE_U8:
+                vec->data.U8[i++] = (psU8)value;
+                break;
+            case PS_TYPE_S32:
+                vec->data.S32[i++] = (psS32)value;
+                break;
+            case PS_TYPE_F32:
+                vec->data.F32[i++] = (psF32)value;
+                break;
+            case PS_TYPE_F64:
+                vec->data.F64[i++] = (psF64)value;
+                break;
+            default:
+                *status = 1;
+                psError(__func__, "Invalid type: %d", elemType);
+            }
+
+            while(*end==' ' || *end==',') {
+                end++;
+            }
+            inString=end;
+        }
+    }
+
+    return vec;
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+void psMetadataItemPrint(FILE * fd, const char *format, const psMetadataItem* restrict metadataItem)
+{
+    psMetadataType type;
+
+    if (fd == NULL) {
+        psError(__func__, "Null file descriptor not allowed");
+        return;
+    }
+
+    if (format == NULL) {
+        psError(__func__, "Null format not allowed");
+        return;
+    }
+
+    if (metadataItem == NULL) {
+        psError(__func__, "Null metadata not allowed");
+        return;
+    }
+
+    type = metadataItem->type;
+
+    switch(type) {
+    case PS_META_BOOL:
+        fprintf(fd, format, metadataItem->data.B);
+        break;
+    case PS_META_S32:
+        fprintf(fd,format, metadataItem->data.S32);
+        break;
+    case PS_META_F32:
+        fprintf(fd, format, metadataItem->data.F32);
+        break;
+    case PS_META_F64:
+        fprintf(fd, format, metadataItem->data.F64);
+        break;
+    case PS_META_STR:
+        fprintf(fd, format, metadataItem->data.V);
+        break;
+    default:
+        psError(__func__, " Invalid psMetadataType to print: %d", type);
+    }
+}
+
+
+psMetadata* psMetadataReadHeader(psMetadata* output, char *extName, int extNum, char *fileName)
+{
+    bool tempBool;
+    bool success;
+    char keyType;
+    char keyName[FITS_LINE_SIZE];
+    char keyValue[FITS_LINE_SIZE];
+    char keyComment[FITS_LINE_SIZE];
+    char fitsErr[MAX_STRING_LENGTH];
+    int i;
+    int hduType = 0;
+    int status = 0;
+    int numKeys = 0;
+    int keyNum = 0;
+    psMetadataType metadataItemType;
+    fitsfile *fd = NULL;
+
+    if(fileName == NULL) {
+        psError(__func__, "Null fileName not allowed");
+        return NULL;
+    }
+
+    fits_open_file(&fd, fileName, READONLY, &status);
+    if(fd == NULL || status != 0) {
+        FITS_ERROR("FITS error while opening file: %s %s", fileName);
+        return NULL;
+    }
+
+    if (extName == NULL && extNum == 0) {
+        psError(__func__, "Null extName and extNum = 0 not allowed");
+        return NULL;
+    } else if (extName && (extNum != -1) ) {
+        psError(__func__, "If extName specified, extNum arguments should be -1.");
+        return NULL;
+    }
+
+    // Allocate metadata if user didn't
+    if (output == NULL) {
+        output = psMetadataAlloc();
+    }
+
+    // Move to user designated HDU number or HDU name in FITS file. HDU numbers starts at one.
+    if (extName != NULL) {
+        if (fits_movnam_hdu(fd, ANY_HDU, extName, 0, &status) != 0) {
+            FITS_ERROR("FITS error while locating header %s: %s", extName);
+        }
+    } else {
+        if (fits_movabs_hdu(fd, extNum, &hduType, &status) != 0) {
+            FITS_ERROR("FITS error while locating header %d: %s", extNum);
+        }
+    }
+
+    // Get number of key names
+    if (fits_get_hdrpos(fd, &numKeys, &keyNum, &status) != 0) {
+        FITS_ERROR("FITS error while reading key %d: %s", keyNum);
+    }
+
+    // Get each key name. Keywords start at one.
+    for (i = 1; i <= numKeys; i++) {
+        if (fits_read_keyn(fd, i, keyName, keyValue, keyComment, &status) != 0) {
+            FITS_ERROR("FITS error while reading key %d: %s", keyNum);
+        }
+        if (fits_get_keytype(keyValue, &keyType, &status) != 0) {
+            fits_get_errstatus(status, fitsErr);
+            if (status != VALUE_UNDEFINED) {
+                FITS_ERROR("FITS error while determining key %d type: %s", keyNum);
+            } else {
+                // Some keywords are still valid if they don't have a type (like COMMENTS and HISTORY)
+                keyType = 'C';
+                status = 0;
+            }
+        }
+
+        switch (keyType) {
+        case 'I':
+            metadataItemType = PS_META_S32;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, metadataItemType, keyComment, atoi(keyValue));
+            break;
+        case 'F':
+            metadataItemType = PS_META_F64;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, metadataItemType, keyComment, atof(keyValue));
+            break;
+        case 'C':
+            metadataItemType = PS_META_STR;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, metadataItemType, keyComment, keyValue);
+            break;
+        case 'L':
+            metadataItemType = PS_META_BOOL;
+            tempBool = (keyValue[0] == 'T') ? 1 : 0;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, metadataItemType, keyComment, tempBool);
+            break;
+        case 'U':
+        case 'X':
+        default:
+            psError(__func__, "Invalid psMetadataType: %c", keyType);
+            return output;
+        }
+
+        if (!success) {
+            psError(__func__, "Failed to add metadata item. Name: %s", keyName);
+            return output;
+        }
+    }
+
+    return output;
+}
+
+
+int psMetadataParseConfig(psMetadata** md, char *fileName, bool overwrite)
+{
+    bool tempBool;
+    char *line = NULL;
+    char *strName = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    char *strComment = NULL;
+    char *linePtr = NULL;
+    int status = 0;
+    int lineCount = 0;
+    int failedLines = 0;
+    psF64 tempDbl = 0.0;
+    psS32 tempInt = 0.0;
+    psMetadataItem *metadataItem = NULL;
+    psVector *tempVec = NULL;
+    FILE *fp = NULL;
+    psElemType elemType;
+    psMetadataType mdType;
+
+
+    // Check for nulls
+    if(fileName == NULL) {
+        psError(__func__, "Null fileName not allowed");
+        return -1;
+    } else if((fp=fopen(fileName, "r")) == NULL) {
+        psError(__func__, "Couldn't open file. Name: %s", fileName);
+        return -1;
+    }
+
+    // Allocate metadata if necessary
+    if (*md == NULL) {
+        *md = psMetadataAlloc();
+    }
+
+    // Create reusable line for continuous read
+    line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char));
+    if (line == NULL) {
+        psAbort(__func__, "Failed to allocate reusable line");
+    }
+
+    // While loop to parse the file
+    while(fgets(line, MAX_STRING_LENGTH, fp) != NULL) {
+
+        // Initialize variables for new line
+        linePtr = line;
+        lineCount++;
+        CLEAR_TEMPS();
+
+        // If line is not a comment or blank, then extract data
+        if(!ignoreLine(linePtr)) {
+
+            // Check for more than one '*' or '@' in a line
+            if(repeatedChars(linePtr, '@') > 1) {
+                failedLines++;
+                psError(__func__, "More than one @ charecter not allowed. Line %d: %s", lineCount, line);
+                continue;
+            } else if(repeatedChars(linePtr, '*') > 1) {
+                failedLines++;
+                psError(__func__, "More than one * charecter not allowed. Line %d: %s", lineCount, line);
+                continue;
+            } else if(repeatedChars(linePtr, '~') > 0) {
+                failedLines++;
+                psError(__func__, "Illegal character. Character:~ Line %d: %s", lineCount, line);
+                continue;
+            }
+
+            // Get metadata item name
+            strName = getToken(&linePtr, " ", &status);
+            if(strName==NULL || status) {
+                failedLines++;
+                status = 0;
+                psError(__func__, "Null name not allowed. Line %d: %s", lineCount, line);
+                continue;
+            }
+
+            // Get the metadata item type
+            strType = getToken(&linePtr, " ", &status);
+            if(strType==NULL) {
+                failedLines++;
+                status = 0;
+                psError(__func__, "Null type not allowed. Line %d: %s", lineCount, line);
+                continue;
+            } else if(!strncmp(strType, "*", 1)) {
+                mdType = PS_META_ITEM_SET;
+            } else if(!strncmp(strType, "STR", 3)) {
+                mdType = PS_META_STR;
+                elemType = PS_TYPE_PTR;
+            } else if(!strncmp(strType, "BOOL", 3)) {
+                mdType = PS_META_BOOL;
+                elemType = PS_TYPE_U8;
+            } else if(!strncmp(strType, "S32", 3)) {
+                mdType = PS_META_S32;
+                elemType = PS_TYPE_S32;
+            } else if(!strncmp(strType, "F32", 3)) {
+                mdType = PS_META_F32;
+                elemType = PS_TYPE_F32;
+            } else if(!strncmp(strType, "F64", 3)) {
+                mdType = PS_META_F64;
+                elemType = PS_TYPE_F64;
+            } else {
+                failedLines++;
+                psError(__func__, "Invalid psMetadataType. Type: %s Line %d: %s", strType, lineCount, line);
+                continue;
+            }
+
+            if(*strName == '@') {
+                mdType = PS_META_VEC;
+            }
+
+            // Get the metadata item value if there is one. Lines with * don't have values.
+            if(mdType != PS_META_ITEM_SET) {
+                strValue = getToken(&linePtr, "#", &status);
+                if(strValue==NULL) {
+                    failedLines++;
+                    status = 0;
+                    psError(__func__, "Null value not allowed. Line %d: %s", lineCount, line);
+                    continue;
+                }
+            }
+
+            // Get the metadata item value if there is one. Not all lines will have comments, so NULL is ok.
+            strComment = getToken(&linePtr,"~", &status);
+            if(status) {
+                failedLines++;
+                status = 0;
+                psError(__func__, "Failed to parse comment. Line %d: %s", lineCount, line);
+                continue;
+            }
+
+            /* If metadata item is found, is not a folder node, and overwrite is allowed, then remove existing
+            and allow switch/case below to add new item. If overwrite is false, then report error. If found
+            item is folder node, then psMetadataAdd will automatically add a new child. */
+            metadataItem = psMetadataLookup(*md, strName);
+            if(metadataItem != NULL) {
+                if(metadataItem->type!=PS_META_ITEM_SET) {
+                    if(overwrite) {
+                        psMetadataRemove(*md, PS_LIST_UNKNOWN, strName);
+                    } else {
+                        failedLines++;
+                        psError(__func__, "Overwrite for name not allowed. Name: %s. Line %d: %s", strName,
+                                lineCount, line);
+                        continue;
+                    }
+                }
+            }
+
+            // Create and add metadata item to metadata and parse values
+            switch (mdType) {
+            case PS_META_ITEM_SET:
+                psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, NULL, NULL);
+                break;
+            case PS_META_BOOL:
+                tempBool = parseBool(strValue, &status);
+                if(!status) {
+                    psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, strComment, tempBool);
+                } else {
+                    status = 0;
+                    failedLines++;
+                    psError(__func__, "Failed to parse value. Value: %s Line %d: %s", strValue, lineCount, line);
+                    continue;
+                }
+                break;
+            case PS_META_S32:
+                tempInt = (psS32)parseValue(strValue, &status);
+                if(!status) {
+                    psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, strComment, tempInt);
+                } else {
+                    status = 0;
+                    failedLines++;
+                    psError(__func__, "Failed to parse value. Value: %s Line %d: %s", strValue, lineCount, line);
+                    continue;
+                }
+                break;
+            case PS_META_F32:
+            case PS_META_F64:
+                tempDbl = parseValue(strValue, &status);
+                if(!status) {
+                    psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, strComment, tempDbl);
+                } else {
+                    status = 0;
+                    failedLines++;
+                    psError(__func__, "Failed to parse value. Value: %s Line %d: %s", strValue, lineCount, line);
+                    continue;
+                }
+                break;
+            case PS_META_STR:
+                psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, strComment, strValue);
+                break;
+            case PS_META_VEC:
+                tempVec = parseVector(strValue, elemType, &status);
+                if(!status) {
+                    psMetadataAdd(*md, PS_LIST_TAIL, strName+1, mdType, strComment, tempVec);
+                } else {
+                    status = 0;
+                    failedLines++;
+                    psError(__func__, "Failed to parse value. Value: %s Line %d: %s", strValue, lineCount, line);
+                    continue;
+                }
+                break;
+            default:
+                failedLines++;
+                psError(__func__, "Invalid psMetadataType. Type: %d Line %d: %s", mdType, lineCount, line);
+                continue;
+            } // switch
+        } // if ignoreLine
+    } // while loop
+
+    psFree(line);
+
+    return failedLines;
+}
Index: /branches/rel3/psLib/src/collections/psMetadataIO.h
===================================================================
--- /branches/rel3/psLib/src/collections/psMetadataIO.h	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psMetadataIO.h	(revision 2163)
@@ -0,0 +1,70 @@
+/** @file  psMetadataIO.h
+*
+*  @brief Contains metadata input/output functions.
+*
+*  This file defines functions to read and write metadata to/from an external file.
+*
+*  @ingroup Metadata
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-06 01:17:39 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#ifndef PS_METADATAIO_H
+#define PS_METADATAIO_H
+
+
+/// @addtogroup Metadata
+/// @{
+
+
+/** Print metadata item to file.
+ *
+ *  Metadata items may be printed to an open file descriptor based on a
+ *  provided format. The format is a sprintf format statement with exactly
+ *  one % formatting command. If the metadata item type is a numeric type,
+ *  this formatting command must also be numeric, and the type conversion
+ *  performed to the value to match the format type. If the metadata type is
+ *  a string, the fromatting command must also be for a string. If the
+ *  metadata type is any other data type, printing is not allowed.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+void psMetadataItemPrint(
+    FILE * fd,                         ///< Pointer to file to write metadata item.
+    const char *format,                ///< Format to print metadata item.
+    const psMetadataItem* restrict metadataItem ///< Metadata item to print.
+);
+
+/** Read metadata header.
+ *
+ *  Read a metadata header from file. If the file is not found, an error is
+ *  reported.
+ *
+ *  @return psMetadata* : Pointer to resulting metadata.
+ */
+psMetadata* psMetadataReadHeader(
+    psMetadata* output,                ///< Resulting metadata from read.
+    char *extName,                     ///< File name extension string.
+    int extNum,                        ///< File name extension number. Starts at 1.
+    char *fileName                     ///< Name of file to read.
+);
+
+/** Read metadata configuration file.
+ *
+ *  Loads pre-defined settings by parsing a configuration file into a psMetadata structure.
+ *
+ *  @return int : Number of lines that failed to be read.
+ */
+int psMetadataParseConfig(
+    psMetadata** md,                   ///< Resulting metadata from read.
+    char *fileName,                    ///< Name of file to read.
+    bool overwrite                     ///< Allow overwrite of duplicate specifications.
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/collections/psScalar.c
===================================================================
--- /branches/rel3/psLib/src/collections/psScalar.c	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psScalar.c	(revision 2163)
@@ -0,0 +1,139 @@
+/** @file  psScalar.c
+ *
+ *  @brief Contains basic scalar definitions and operations
+ *
+ *  This file defines the basic type for a scalar struct and functions useful
+ *  in manupulating scalars.
+ * *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-12 19:32:44 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psScalar.h"
+#include "psLogMsg.h"
+#include "psAbort.h"
+
+#include "psCollectionsErrors.h"
+
+psScalar* psScalarAlloc(psC64 value, psElemType dataType)
+{
+    psScalar* scalar = NULL;
+
+    // Create scalar
+    scalar = (psScalar* ) psAlloc(sizeof(psScalar));
+
+    scalar->type.dimen = PS_DIMEN_SCALAR;
+    scalar->type.type = dataType;
+
+    switch (dataType) {
+    case PS_TYPE_S8:
+        scalar->data.S8 = (psS8) value;
+        break;
+    case PS_TYPE_U8:
+        scalar->data.U8 = (psU8) value;
+        break;
+    case PS_TYPE_S16:
+        scalar->data.S16 = (psS16) value;
+        break;
+    case PS_TYPE_U16:
+        scalar->data.U16 = (psU16) value;
+        break;
+    case PS_TYPE_S32:
+        scalar->data.S32 = (psS32) value;
+        break;
+    case PS_TYPE_U32:
+        scalar->data.U32 = (psU32) value;
+        break;
+    case PS_TYPE_S64:
+        scalar->data.S64 = (psS64) value;
+        break;
+    case PS_TYPE_U64:
+        scalar->data.U64 = (psU64) value;
+        break;
+    case PS_TYPE_F32:
+        scalar->data.F32 = (psF32) value;
+        break;
+    case PS_TYPE_F64:
+        scalar->data.F64 = (psF64) value;
+        break;
+    case PS_TYPE_C32:
+        scalar->data.C32 = (psC32) value;
+        break;
+    case PS_TYPE_C64:
+        scalar->data.C64 = (psC64) value;
+        break;
+    default:
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psScalarAlloc",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psScalar_UNSUPPORTED_TYPE,
+                   dataType);
+    }
+
+    return scalar;
+}
+
+psScalar* psScalarCopy(psScalar *scalar)
+{
+    psElemType dataType;
+    psScalar *newScalar = NULL;
+
+    if (scalar == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psScalarCopy",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psScalar_COPY_NULL);
+        return NULL;
+    }
+
+    dataType = scalar->type.type;
+    switch (dataType) {
+    case PS_TYPE_S8:
+        newScalar =  psScalarAlloc(scalar->data.S8, dataType);
+        break;
+    case PS_TYPE_U8:
+        newScalar =  psScalarAlloc(scalar->data.U8, dataType);
+        break;
+    case PS_TYPE_S16:
+        newScalar =  psScalarAlloc(scalar->data.S16, dataType);
+        break;
+    case PS_TYPE_U16:
+        newScalar =  psScalarAlloc(scalar->data.U16, dataType);
+        break;
+    case PS_TYPE_S32:
+        newScalar =  psScalarAlloc(scalar->data.S32, dataType);
+        break;
+    case PS_TYPE_U32:
+        newScalar =  psScalarAlloc(scalar->data.U32, dataType);
+        break;
+    case PS_TYPE_S64:
+        newScalar =  psScalarAlloc(scalar->data.S64, dataType);
+        break;
+    case PS_TYPE_U64:
+        newScalar =  psScalarAlloc(scalar->data.U64, dataType);
+        break;
+    case PS_TYPE_F32:
+        newScalar =  psScalarAlloc(scalar->data.F32, dataType);
+        break;
+    case PS_TYPE_F64:
+        newScalar =  psScalarAlloc(scalar->data.F64, dataType);
+        break;
+    case PS_TYPE_C32:
+        newScalar =  psScalarAlloc(scalar->data.C32, dataType);
+        break;
+    case PS_TYPE_C64:
+        newScalar =  psScalarAlloc(scalar->data.C64, dataType);
+        break;
+    default:
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psScalarCopy",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psScalar_UNSUPPORTED_TYPE,
+                   dataType);
+    }
+
+    return newScalar;
+}
Index: /branches/rel3/psLib/src/collections/psScalar.h
===================================================================
--- /branches/rel3/psLib/src/collections/psScalar.h	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psScalar.h	(revision 2163)
@@ -0,0 +1,84 @@
+
+/** @file  psScalar.h
+ *
+ *  @brief Contains basic scalar definitions and operations
+ *
+ *  This file defines the basic type for a scalar struct and functions useful
+ *  in manupulating scalars.
+ *
+ *  @ingroup Scalar
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-12 19:32:44 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_SCALAR_H
+#define PS_SCALAR_H
+
+#include "psType.h"
+
+/// @addtogroup Scalar
+/// @{
+
+/** Basic scalar data structure.
+ *
+ * Struct for maintaining a scalar of frequently used primitive types.
+ *
+ */
+typedef struct
+{
+    psType type;                ///< Type of data.
+
+    union {
+        psU8 U8;                ///< Unsigned 8-bit integer data.
+        psU16 U16;              ///< Unsigned 16-bit integer data.
+        psU32 U32;              ///< Unsigned 32-bit integer data.
+        psU64 U64;              ///< Unsigned 64-bit integer data.
+        psS8 S8;                ///< Signed 8-bit integer data.
+        psS16 S16;              ///< Signed 16-bit integer data.
+        psS32 S32;              ///< Signed 32-bit integer data.
+        psS64 S64;              ///< Signed 64-bit integer data.
+        psF32 F32;              ///< Single-precision float data.
+        psF64 F64;              ///< Double-precision float data.
+        psC32 C32;              ///< Single-precision complex data.
+        psC64 C64;              ///< Double-precision complex data.
+    } data;                     ///< Union for data types.
+}
+psScalar;
+
+/*****************************************************************************/
+
+/* FUNCTION PROTOTYPES                                                       */
+
+/*****************************************************************************/
+
+/** Allocate a scalar.
+ *
+ * Uses psLib memory allocation functions to create scalar data as defined by the psType type.
+ * Accepts a complex 64 bit float for input value, as max size, but resizes according to
+ * correct type.
+ *
+ * @return psScalar*   Pointer to a new psScalar.
+ */
+psScalar* psScalarAlloc(
+    psC64 value,                       ///< Data to be put into psScalar.
+    psElemType dataType                ///< Type of data to be held by psScalar.
+);
+
+/** Copy a scalar.
+ *
+ * Uses psLib memory allocation functions to copy a scalar.
+ *
+ * @return psScalar*    A copy of the input scalar
+ */
+psScalar* psScalarCopy(
+    psScalar *scalar                   ///< Scalar to copy.
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/collections/psVector.c
===================================================================
--- /branches/rel3/psLib/src/collections/psVector.c	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psVector.c	(revision 2163)
@@ -0,0 +1,412 @@
+
+/** @file  psVector.c
+*
+*  @brief Contains support for basic vector types
+*
+*  This file defines the basic type for a vector struct and functions useful
+*  in manupulating vectors.
+*
+*  @author Ross Harman, MHPCC
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.28 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-07 19:51:30 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include <string.h>                        // for memcpy
+#include <stdlib.h>
+#include <math.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psVector.h"
+#include "psLogMsg.h"
+#include "psCompare.h"
+
+#include "psCollectionsErrors.h"
+
+static void vectorFree(psVector* restrict psVec);
+
+
+static void vectorFree(psVector* restrict psVec)
+{
+    if (psVec == NULL) {
+        return;
+    }
+
+    psFree(psVec->data.V);
+}
+
+// FUNCTION IMPLEMENTATION - PUBLIC
+
+psVector* psVectorAlloc(unsigned int nalloc, psElemType elemType)
+{
+    psVector* psVec = NULL;
+    int elementSize = 0;
+
+    elementSize = PSELEMTYPE_SIZEOF(elemType);
+
+    // Create vector struct
+    psVec = (psVector* ) psAlloc(sizeof(psVector));
+    p_psMemSetDeallocator(psVec, (psFreeFcn) vectorFree);
+
+    psVec->type.dimen = PS_DIMEN_VECTOR;
+    psVec->type.type = elemType;
+    psVec->nalloc = nalloc;
+    psVec->n = nalloc;
+
+    // Create vector data array
+    psVec->data.V = psAlloc(nalloc * elementSize);
+
+    return psVec;
+}
+
+psVector* psVectorRealloc(psVector* restrict in, unsigned int nalloc)
+{
+    int elementSize = 0;
+    psElemType elemType;
+
+    if (in == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorRealloc",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psVector_REALLOC_NULL);
+        return NULL;
+    } else if (in->nalloc != nalloc) {     // No need to realloc to same size
+        elemType = in->type.type;
+        elementSize = PSELEMTYPE_SIZEOF(elemType);
+        if (nalloc < in->n) {
+            in->n = nalloc;
+        }
+        // Realloc after decrementation to avoid accessing freed array elements
+        in->data.V = psRealloc(in->data.V, nalloc * elementSize);
+        in->nalloc = nalloc;
+    }
+
+    return in;
+}
+
+psVector* psVectorRecycle(psVector* restrict in, unsigned int n, psElemType type)
+{
+    int byteSize;
+
+    if (in == NULL) {
+        return psVectorAlloc(n, type);
+    }
+
+    if (in->type.dimen !=  PS_DIMEN_VECTOR &&
+            in->type.dimen !=  PS_DIMEN_TRANSV) {
+        psFree(in);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorRecycle",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVector_NOT_A_VECTOR);
+        return NULL;
+    }
+
+    byteSize = n * PSELEMTYPE_SIZEOF(type);
+
+    // need to increase data buffer?
+    if (byteSize > in->nalloc*PSELEMTYPE_SIZEOF(in->type.type)) {
+        in->data.V = psRealloc(in->data.V, byteSize);
+        in->nalloc = n;
+    }
+
+    in->type.dimen = PS_DIMEN_VECTOR;
+    in->type.type = type;
+    in->n = n;
+    return in;
+}
+
+psVector* psVectorCopy(psVector* out, const psVector* in, psElemType type)
+{
+    if (in == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorSort",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psVector_SORT_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    int nElements = in->n;
+
+    out = psVectorRecycle(out, nElements, type);
+
+    #define PSVECTOR_COPY(INTYPE,OUTTYPE) { \
+        ps##INTYPE *inVec = in->data.INTYPE; \
+        ps##OUTTYPE *outVec = out->data.OUTTYPE; \
+        for (int col=0;col<nElements;col++) { \
+            *(outVec++) = *(inVec++); \
+        } \
+    }
+
+    #define PSVECTOR_COPY_CASE(OUTTYPE) \
+case PS_TYPE_##OUTTYPE: { \
+        switch (in->type.type) { \
+        case PS_TYPE_S8: \
+            PSVECTOR_COPY(S8,OUTTYPE); \
+            break; \
+        case PS_TYPE_S16: \
+            PSVECTOR_COPY(S16,OUTTYPE); \
+            break; \
+        case PS_TYPE_S32: \
+            PSVECTOR_COPY(S32,OUTTYPE); \
+            break; \
+        case PS_TYPE_S64: \
+            PSVECTOR_COPY(S64,OUTTYPE); \
+            break; \
+        case PS_TYPE_U8: \
+            PSVECTOR_COPY(U8,OUTTYPE); \
+            break; \
+        case PS_TYPE_U16: \
+            PSVECTOR_COPY(U16,OUTTYPE); \
+            break; \
+        case PS_TYPE_U32: \
+            PSVECTOR_COPY(U32,OUTTYPE); \
+            break; \
+        case PS_TYPE_U64: \
+            PSVECTOR_COPY(U64,OUTTYPE); \
+            break; \
+        case PS_TYPE_F32: \
+            PSVECTOR_COPY(F32,OUTTYPE); \
+            break; \
+        case PS_TYPE_F64: \
+            PSVECTOR_COPY(F64,OUTTYPE); \
+            break; \
+        case PS_TYPE_C32: \
+            PSVECTOR_COPY(C32,OUTTYPE); \
+            break; \
+        case PS_TYPE_C64: \
+            PSVECTOR_COPY(C64,OUTTYPE); \
+            break; \
+        default: { \
+                char* typeStr; \
+                PS_TYPE_NAME(typeStr,type); \
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCopy", \
+                           PS_ERR_BAD_PARAMETER_TYPE, true, \
+                           PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE, \
+                           typeStr); \
+                psFree(out); \
+            } \
+        } \
+        break; \
+    }
+
+    switch (type) {
+        PSVECTOR_COPY_CASE(S8);
+        PSVECTOR_COPY_CASE(S16);
+        PSVECTOR_COPY_CASE(S32);
+        PSVECTOR_COPY_CASE(S64);
+        PSVECTOR_COPY_CASE(U8);
+        PSVECTOR_COPY_CASE(U16);
+        PSVECTOR_COPY_CASE(U32);
+        PSVECTOR_COPY_CASE(U64);
+        PSVECTOR_COPY_CASE(F32);
+        PSVECTOR_COPY_CASE(F64);
+        PSVECTOR_COPY_CASE(C32);
+        PSVECTOR_COPY_CASE(C64);
+    default: {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCopy",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE,
+                       typeStr);
+            psFree(out);
+
+            break;
+        }
+    }
+    return out;
+
+
+}
+
+psVector* psVectorSort(psVector* restrict outVector, const psVector* restrict inVector)
+{
+    int N = 0;
+    int elSize = 0;
+    void *inVec = NULL;
+    void *outVec = NULL;
+    psElemType inType = 0;
+
+    if (inVector == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorSort",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psVector_SORT_NULL);
+        psFree(outVector);
+        return NULL;
+    }
+
+    inType = inVector->type.type;
+    N = inVector->n;
+    inVec = inVector->data.V;
+    elSize = PSELEMTYPE_SIZEOF(inType);
+
+    if (outVector == NULL) {
+        outVector = psVectorAlloc(N, inType);
+    }
+
+    // check to see if output vector needs to be resized/retyped
+    if ( (N > outVector->nalloc) ||
+            (inType != outVector->type.type) ) {
+        // reshape the output vector to match the input vector's size/type.
+        outVector = psVectorRecycle(outVector,N,inType);
+    }
+    outVector->n = N;
+    outVec = outVector->data.V;
+
+    if (N == 0) {
+        // no need to sort anything, as there are no elements in input vector.
+        return outVector;
+    }
+
+    // Copy input vector values into output vector if not in-place sorting
+    if (inVector != outVector) {
+        memcpy(outVec, inVec, elSize * N);
+    }
+
+    // Sort output vector
+    switch (inType) {
+    case PS_TYPE_U8:
+        qsort(outVec, N, elSize, psCompareU8);
+        break;
+    case PS_TYPE_U16:
+        qsort(outVec, N, elSize, psCompareU16);
+        break;
+    case PS_TYPE_U32:
+        qsort(outVec, N, elSize, psCompareU32);
+        break;
+    case PS_TYPE_U64:
+        qsort(outVec, N, elSize, psCompareU64);
+        break;
+    case PS_TYPE_S8:
+        qsort(outVec, N, elSize, psCompareS8);
+        break;
+    case PS_TYPE_S16:
+        qsort(outVec, N, elSize, psCompareS16);
+        break;
+    case PS_TYPE_S32:
+        qsort(outVec, N, elSize, psCompareS32);
+        break;
+    case PS_TYPE_S64:
+        qsort(outVec, N, elSize, psCompareS64);
+        break;
+    case PS_TYPE_F32:
+        qsort(outVec, N, elSize, psCompareF32);
+        break;
+    case PS_TYPE_F64:
+        qsort(outVec, N, elSize, psCompareF64);
+        break;
+    default:
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorSort",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE,
+                   inType);
+    }
+
+    return outVector;
+}
+
+psVector* psVectorSortIndex(psVector* restrict outVector, const psVector* restrict inVector)
+{
+    int N = 0;
+    psVector* tmpVector = NULL;
+    psElemType inType = 0;
+    psU32* outVec;
+
+    if (inVector == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorSortIndex",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psVector_SORT_NULL);
+        psFree(outVector);
+        return NULL;
+    }
+
+    N = inVector->n;
+
+    if (outVector == NULL) {
+        outVector = psVectorAlloc(N, PS_TYPE_U32);
+    }
+
+    // check to see if output vector needs to be resized/retyped
+    if ( (N > outVector->nalloc) ||
+            (outVector->type.type != PS_TYPE_U32) ) {
+        // reshape the output vector to match the input vector's size/type.
+        outVector = psVectorRecycle(outVector,N,PS_TYPE_U32);
+    }
+    outVector->n = N;
+    outVec = outVector->data.U32;
+
+    if (N == 0) {
+        // no need to sort anything, as there are no elements in input vector.
+        return outVector;
+    }
+
+    tmpVector = psVectorSort(tmpVector, inVector);
+
+    #define SORT_INDICES(TYPE,absfcn,maxError) {                              \
+        ps##TYPE* inVec = inVector->data.TYPE;                                \
+        ps##TYPE* tmpVec = tmpVector->data.TYPE;                              \
+        ps##TYPE  diff;                                                       \
+        for(int i=0; i<N; i++) {                                              \
+            for(int j=0; j<N; j++) {                                          \
+                diff = absfcn(tmpVec[i] - inVec[j]);                          \
+                if(diff < maxError) {                                         \
+                    outVec[i] = j;                                            \
+                    break;                                                    \
+                }                                                             \
+            }                                                                 \
+        }                                                                     \
+    }
+
+    // Sort output vector
+    switch (inType) {
+    case PS_TYPE_U8:
+        SORT_INDICES(U8,/* no absfcn needed */,1);
+        break;
+    case PS_TYPE_U16:
+        SORT_INDICES(U16,/* no absfcn needed */,1);
+        break;
+    case PS_TYPE_U32:
+        SORT_INDICES(U32,/* no absfcn needed */,1);
+        break;
+    case PS_TYPE_U64:
+        SORT_INDICES(U64,/* no absfcn needed */,1);
+        break;
+    case PS_TYPE_S8:
+        SORT_INDICES(S8,/* no absfcn needed */,1);
+        break;
+    case PS_TYPE_S16:
+        SORT_INDICES(S16,/* no absfcn needed */,1);
+        break;
+    case PS_TYPE_S32:
+        SORT_INDICES(S32,/* no absfcn needed */,1);
+        break;
+    case PS_TYPE_S64:
+        SORT_INDICES(S64,/* no absfcn needed */,1);
+        break;
+    case PS_TYPE_F32:
+        SORT_INDICES(F32,fabsf,FLT_EPSILON);
+        break;
+    case PS_TYPE_F64:
+        SORT_INDICES(F64,fabs,DBL_EPSILON);
+        break;
+    case PS_TYPE_C32:
+        SORT_INDICES(F64,cabsf,FLT_EPSILON);
+        break;
+    case PS_TYPE_C64:
+        SORT_INDICES(F64,cabs,DBL_EPSILON);
+        break;
+    default:
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorSortIndex",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE,
+                   inType);
+    }
+
+    // Free temp memory
+    psFree(tmpVector);
+
+    return outVector;
+}
Index: /branches/rel3/psLib/src/collections/psVector.h
===================================================================
--- /branches/rel3/psLib/src/collections/psVector.h	(revision 2163)
+++ /branches/rel3/psLib/src/collections/psVector.h	(revision 2163)
@@ -0,0 +1,147 @@
+/** @file  psVector.h
+ *
+ *  @brief Contains basic vector definitions and operations
+ *
+ *  This file defines the basic type for a vector struct and functions useful
+ *  in manupulating vectors.
+ *
+ *  @ingroup Vector
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.24 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-06 21:30:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_VECTOR_H
+#define PS_VECTOR_H
+
+#include "psType.h"
+
+/// @addtogroup Vector
+/// @{
+
+/** An vector to support primitive types.
+ *
+ * Struct for maintaining an vector of frequently used primitive types.
+ *
+ */
+typedef struct
+{
+    psType type;                ///< Type of data.
+    unsigned int nalloc;        ///< Total number of elements available.
+    unsigned int n;             ///< Number of elements in use.
+
+    union {
+        psU8* U8;               ///< Unsigned 8-bit integer data.
+        psU16* U16;             ///< Unsigned 16-bit integer data.
+        psU32* U32;             ///< Unsigned 32-bit integer data.
+        psU64* U64;             ///< Unsigned 64-bit integer data.
+        psS8* S8;               ///< Signed 8-bit integer data.
+        psS16* S16;             ///< Signed 16-bit integer data.
+        psS32* S32;             ///< Signed 32-bit integer data.
+        psS64* S64;             ///< Signed 64-bit integer data.
+        psF32* F32;             ///< Single-precision float data.
+        psF64* F64;             ///< Double-precision float data.
+        psC32* C32;             ///< Single-precision complex data.
+        psC64* C64;             ///< Double-precision complex data.
+        psPTR V;                ///< Pointer to data.
+    } data;                     ///< Union for data types.
+}
+psVector;
+
+/*****************************************************************************/
+
+/* FUNCTION PROTOTYPES                                                       */
+
+/*****************************************************************************/
+
+
+/** Allocate a vector.
+ *
+ *  Uses psLib memory allocation functions to create a vector collection of 
+ *  data as defined by the psType type.
+ *
+ * @return psVector*    Pointer to psVector.
+ */
+psVector* psVectorAlloc(
+    unsigned int nalloc,               ///< Total number of elements to make available.
+    psElemType dataType                ///< Type of data to be held by vector.
+);
+
+/** Reallocate a vector.
+ *
+ *  Uses psLib memory allocation functions to reallocate a vector collection 
+ *  of data. The vector is reallocated according to the psType type member 
+ *  contained within the vector.
+ *
+ *  @return psVector*      Pointer to psVector.
+ *
+ */
+psVector* psVectorRealloc(
+    psVector* restrict psVec,          ///< Vector to reallocate.
+    unsigned int nalloc                ///< Total number of elements to make available.
+);
+
+/** Recycle a vector.
+ *
+ *  Uses psLib memory allocation functions to reallocate a vector collection 
+ *  of data. The vector is reallocated according to the psElemType type 
+ *  parameter.
+ *
+ * @return psVector*       Pointer to psVector.
+ *
+ */
+psVector* psVectorRecycle(
+    psVector* restrict psVec,
+    ///< Vector to recycle.  If NULL, a new vector is created.  No effort
+    ///< taken to preserve the values.
+
+    unsigned int nalloc,               ///< Total number of elements to make available.
+    psElemType type                    ///< the datatype of the returned vector
+);
+
+/** Copy a vector, converting types.
+ *
+ *  Performs a deep copy of the elements of one psVector to a new psVector, 
+ *  converting numeric types to a specified type.
+ *
+ * @return psVector*       Pointer to resulting psVector.
+ *
+ */
+psVector* psVectorCopy(
+    psVector* out,                     ///< if non-NULL, a psVector to recycle
+    const psVector* in,                ///< the vector to copy.
+    psElemType type                    ///< the data type of the resulting psVector
+);
+
+/** Sort an array of floats.
+ *
+ *  Sorts an array of floats in ascending order.  This function is valid for
+ *  all non-complex data types.
+ *
+ *  @return  psVector*     Pointer to sorted psVector.
+ */
+psVector* psVectorSort(
+    psVector* restrict outVector,      ///< the output vector to recycle, or NULL if new vector desired.
+    const psVector* restrict inVector  ///< the vector to sort.
+);
+
+/** Creates an array of indices based on sort ordered of array.
+ *
+ *  Sorts a vector and creates an integer array holding indices of 
+ *  sorted float values based on pre-sort index positions.  
+ *
+ *  @return  psVector*     vector of the indices of sort.
+ */
+psVector* psVectorSortIndex(
+    psVector* restrict outVector,      ///< vector to recycle
+    const psVector* restrict inVector  ///< vector to sort
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/dataManip/.cvsignore
===================================================================
--- /branches/rel3/psLib/src/dataManip/.cvsignore	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/.cvsignore	(revision 2163)
@@ -0,0 +1,1 @@
+*.i
Index: /branches/rel3/psLib/src/dataManip/Makefile
===================================================================
--- /branches/rel3/psLib/src/dataManip/Makefile	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/Makefile	(revision 2163)
@@ -0,0 +1,68 @@
+ifndef prefix
+    export prefix=$(shell cd ../..;pwd)
+endif
+
+TARGET_STATIC  = libpslib.a
+include ../Makefile.Globals
+CFLAGS := $(CFLAGS_RELOC) -I. -I../sysUtils -I../collections -I.. -I../image -I..
+
+SRC_OBJS = psStats.o  \
+           psFunctions.o \
+           psMatrix.o \
+           psMatrixVectorArithmetic.o \
+           psVectorFFT.o \
+           psMinimize.o \
+ 
+OBJS = $(addprefix makedir/,$(SRC_OBJS))
+ 
+HEADERS = $(SRC_OBJS:.o=.h)
+         
+all: $(TARGET_STATIC)
+
+psDataManipErrors.h: psDataManipErrors.dat
+	perl ../parseErrorCodes.pl --data=$? $@
+
+# force the creation of a psImage.i for psImage.o (to expand macros).
+psMatrixVectorArithmetic.o: psMatrixVectorArithmetic.i
+
+# Rule to make static library
+
+libpslib.a:     $(OBJS)
+# The ar option -r is to add/replace object and -s is to create
+# a symbol table in the archive
+	$(AR) rcs ../$@ $(OBJS)
+
+# Define PHONY target "install" which will install necessary files
+# XXX: Do the psConstants.h install.
+install: $(TARGET_STATIC)
+	install $(HEADERS) $(includedir)
+	install psConstants.h $(includedir)
+
+
+# Define PHONY target "distclean" which will cleanup the distribution
+distclean:      clean
+	$(RM) ../$(TARGET_STATIC)
+
+# Define PHONY target "clean" which will cleanup the development area
+clean:
+	@echo "    Deleting intermediate files for 'sysUtils'"
+	$(RM) $(OBJS) *.lint $(SRC_OBJS:.o=.i)
+
+cleandep:
+	$(RM) $(OBJS:.o=.d)
+
+%.lint: %.c
+	splint +posixlib -exportlocal -realcompare $(INCLUDE_GLOBAL) $? > $@; cat $@
+
+%.i: %.c
+	$(CC) -E $(CFLAGS) -o $@ $<
+
+makedir/%.o: %.c
+	$(CC) -c $(CFLAGS) -o $@ $<
+
+makedir/%.d: %.c
+	$(CC) -MM $(CFLAGS) $< > $@.tmp
+	sed 's|\($*\)\.o[ :]*|\1.o $@ : |g' $@.tmp > $@
+	$(RM) -f $@.tmp
+
+include $(OBJS:.o=.d)
Index: /branches/rel3/psLib/src/dataManip/psConstants.h
===================================================================
--- /branches/rel3/psLib/src/dataManip/psConstants.h	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/psConstants.h	(revision 2163)
@@ -0,0 +1,205 @@
+/** @file  psComments.h
+ *
+ *  This file will hold definitions of various constants as well as common
+ *  macros used throughout psLib.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 23:43:12 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#define DETERMINE_BRACKET_STEP_SIZE 0.10
+#define MAX_LMM_ITERATIONS 100
+#define MAX_MINIMIZE_ITERATIONS 100
+#define LEFT_SPLINE_DERIV 0.0
+#define RIGHT_SPLINE_DERIV 0.0
+
+#define CONVERT_VECTOR_F64_TO_F32(OLD, NEW_PTR32, NEW_STATIC32) \
+if (OLD->type.type == PS_TYPE_F32) { \
+    NEW_PTR32 = (psVector *) OLD; \
+} else if (OLD->type.type == PS_TYPE_F64) { \
+    NEW_STATIC32 = psVectorRecycle(NEW_STATIC32, OLD->n, PS_TYPE_F32); \
+    p_psMemSetPersistent(NEW_STATIC32, true); \
+    p_psMemSetPersistent(NEW_STATIC32->data.V, true); \
+    for (i=0; i < OLD->n ; i++) { \
+        NEW_STATIC32->data.F32[i] = (float) OLD->data.F64[i]; \
+    } \
+    NEW_PTR32 = NEW_STATIC32; \
+} \
+
+#define CONVERT_VECTOR_F32_TO_F64(OLD, NEW_PTR64, NEW_STATIC64) \
+if (OLD->type.type == PS_TYPE_F64) { \
+    NEW_PTR64 = (psVector *) OLD; \
+} else if (OLD->type.type == PS_TYPE_F32) { \
+    NEW_STATIC64 = psVectorRecycle(NEW_STATIC64, OLD->n, PS_TYPE_F64); \
+    p_psMemSetPersistent(NEW_STATIC64, true); \
+    p_psMemSetPersistent(NEW_STATIC64->data.V, true); \
+    for (i=0; i < OLD->n ; i++) { \
+        NEW_STATIC64->data.F64[i] = (double) OLD->data.F32[i]; \
+    } \
+    NEW_PTR64 = NEW_STATIC64; \
+} \
+
+#define VECTOR_CHECK_TYPE_F32_OR_F64_RETURN_NULL(VEC) \
+if ((VEC->type.type != PS_TYPE_F32) && (VEC->type.type != PS_TYPE_F64)) { \
+    psAbort(__func__, "Bad type for VEC (%d)", VEC->type.type); \
+    return(NULL); \
+} \
+
+#define GEN_PERSIST_YERR_VEC_F32(VEC, N) \
+VEC = psVectorRecycle(VEC, N, PS_TYPE_F32); \
+p_psMemSetPersistent(VEC, true); \
+p_psMemSetPersistent(VEC->data.V, true); \
+for (int i=0;i<N;i++) { \
+    VEC->data.F32[i] = 1.0; \
+} \
+
+#define GEN_PERSIST_YERR_VEC_F64(VEC, N) \
+VEC = psVectorRecycle(VEC, N, PS_TYPE_F64); \
+p_psMemSetPersistent(VEC, true); \
+p_psMemSetPersistent(VEC->data.V, true); \
+for (int i=0;i<N;i++) { \
+    VEC->data.F64[i] = 1.0; \
+} \
+
+#define GEN_PERSIST_X_INDEX_VEC_F32(VEC, N) \
+VEC = psVectorRecycle(VEC, N, PS_TYPE_F32); \
+p_psMemSetPersistent(VEC, true); \
+p_psMemSetPersistent(VEC->data.V, true); \
+for (int i=0;i<N;i++) { \
+    VEC->data.F32[i] = (float) i; \
+} \
+
+#define GEN_PERSIST_X_INDEX_VEC_F64(VEC, N) \
+VEC = psVectorRecycle(VEC, N, PS_TYPE_F64); \
+p_psMemSetPersistent(VEC, true); \
+p_psMemSetPersistent(VEC->data.V, true); \
+for (int i=0;i<N;i++) { \
+    VEC->data.F64[i] = (float) i; \
+} \
+
+#define GEN_STATIC_RECYCLED_VECTOR(NAME, SIZE, TYPE) \
+static psVector *NAME = NULL; \
+NAME = psVectorRecycle(NAME, SIZE, TYPE); \
+p_psMemSetPersistent(NAME, true); \
+p_psMemSetPersistent(NAME->data.V, true); \
+
+
+
+
+
+
+/** Preprocessor macro to generate error on an incorrect type */
+#define PS_CHECK_VECTOR_TYPE_RETURN_NULL(NAME, TYPE) \
+if (NAME->type.type != TYPE) { \
+    psError(__func__,"Unallowable operation: %s has incorrect type.", #NAME); \
+    return(NULL); \
+}
+
+/** Preprocessor macro to generate error on a NULL vector */
+#define PS_CHECK_NULL_VECTOR_RETURN_NULL(NAME) \
+if (NAME == NULL || NAME->data.V == NULL) { \
+    psError(__func__,"Unallowable operation: %s or its data is NULL.", #NAME); \
+    return(NULL); \
+} \
+
+/** Preprocessor macro to generate error on a NULL poniter */
+#define PS_CHECK_NULL_PTR_RETURN_NULL(NAME) \
+if (NAME == NULL) { \
+    psError(__func__,"Unallowable operation: %s is NULL.", #NAME); \
+    return(NULL); \
+}
+/** Preprocessor macro to generate error on a NULL poniter */
+#define PS_CHECK_NULL_PTR_RETURN_ZERO(NAME) \
+if (NAME == NULL) { \
+    psError(__func__,"Unallowable operation: %s is NULL.", #NAME); \
+    return(0); \
+}
+
+/** Preprocessor macro to generate error for zero length vector */
+#define PS_CHECK_EMPTY_VECTOR_RETURN_NULL(NAME) \
+if (NAME->n < 1) { \
+    psError(__func__,"Unallowable operation: %s has zero n value.", #NAME); \
+    return(NULL); \
+} \
+
+/** Preprocessor macro to generate error on differing size vectors */
+#define PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(VEC1, VEC2) \
+if (VEC1->n != VEC2->n) { \
+    psError(__func__,"Vector %s has size %d, Vector %s has size %d.", #VEC1, VEC1->n, #VEC2, VEC2->n); \
+    return(NULL); \
+}
+
+/** Preprocessor macro to generate error on differing size vectors */
+#define PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(VEC1, VEC2) \
+if (VEC1->n != VEC2->n) { \
+    psError(__func__,"Vector %s has size %d, Vector %s has size %d.", #VEC1, VEC1->n, #VEC2, VEC2->n); \
+    return(NULL); \
+}
+
+/** Preprocessor macro to generate error on a NULL image */
+#define PS_CHECK_NULL_IMAGE_RETURN_NULL(NAME) \
+if (NAME == NULL || NAME->data.V == NULL) {                                                         \
+    psError(__func__,"Unallowable operation: %s or its data is NULL.", #NAME);                          \
+    return(NULL); \
+}
+
+/** Preprocessor macro to generate error for zero length rows or columns */
+#define PS_CHECK_EMPTY_IMAGE_RETURN_NULL(NAME) \
+if (NAME->numCols < 1 || NAME->numRows < 1) {                                                       \
+    psError(__func__,"Unallowable operation: %s has zero rows or columns (%dx%d).", #NAME,              \
+            NAME->numCols, NAME->numRows);                                                          \
+    return(NULL); \
+}
+
+#define PS_CHECK_IMAGE_TYPE_RETURN_NULL(NAME, TYPE) \
+if (NAME->type.type != TYPE) { \
+    psError(__func__,"Unallowable operation: %s has incorrect type.", #NAME); \
+    return(NULL); \
+}
+
+/** Preprocessor macro to generate error on a NULL image */
+#define PS_CHECK_NULL_IMAGE_READOUT_NULL(NAME) \
+if (NAME == NULL || NAME->image == NULL) {                                                         \
+    psError(__func__,"Unallowable operation: %s or its data is NULL.", #NAME);                          \
+    return(NULL); \
+}
+
+#define PS_CHECK_NULL_1DPOLY_RETURN_NULL(NAME)                                                          \
+if (NAME == NULL || NAME->coeff == NULL) {                                                         \
+    psError(__func__,"Unallowable operation: %s or its coeffs is NULL.", #NAME);                          \
+    return(NULL); \
+} \
+
+
+
+
+
+#define PS_PRINT_VECTOR(NAME) \
+for (int my_i=0;my_i<NAME->n;my_i++) { \
+    printf("%s->data.F32[%d] is %f\n", #NAME, my_i, NAME->data.F32[my_i]); \
+} \
+printf("\n"); \
+
+#define PS_VECTOR_F64_TO_F32(X64, X32) \
+psVector *X32 = psVectorAlloc(X64->n, PS_TYPE_F32); \
+for (int i=0;i<X64->n;i++) { \
+    X32->data.F32[i] = (float) X64->data.F64[i]; \
+} \
+
+#define PS_VECTOR_F32_TO_F64(X32, X64) \
+psVector *X64 = psVectorAlloc(X32->n, PS_TYPE_F64); \
+for (int i=0;i<X32->n;i++) { \
+    X64->data.F64[i] = (float) X32->data.F32[i]; \
+} \
+
+
+#define PS_MAX(A, B) \
+((A > B) ? A : B) \
+
+#define PS_MIN(A, B) \
+((A < B) ? A : B) \
+
Index: /branches/rel3/psLib/src/dataManip/psDataManipErrors.dat
===================================================================
--- /branches/rel3/psLib/src/dataManip/psDataManipErrors.dat	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/psDataManipErrors.dat	(revision 2163)
@@ -0,0 +1,19 @@
+#
+#  This file is used to generate psDataManipErrors.h content
+#
+#  Format is:
+#  ERRORNAME(one word)    ERROR_TEXT
+#
+#  N.B. in code, the ERRORNAME appears as PS_ERRORTEXT_ERRORNAME
+####################################################################
+#
+psVectorFFT_IMAGE_TYPE_UNSUPPORTED     Input psVector type, %s, is not supported. Valid data types are psF32 and psC32.
+psVectorFFT_REVERSE_NOT_COMPLEX        Input psVector (%s) is not complex.  Reverse FFT operation requires a complex input.
+psVectorFFT_FORWARD_NOT_REAL           Input psVector (%s) is not real.  Forward FFT operation requires a real input.
+psVectorFFT_FFTW_PLAN_NULL             Could not create a valid FFT plan to perform the transform.
+psVectorFFT_TYPE_UNSUPPORTED           Specified psVector type, %s, is not supported.
+psVectorFFT_REAL_IMAG_TYPE_MISMATCH    Real psVector type, %s, and imaginary psVector type, %s, must be the same.
+psVectorFFT_REAL_IMAG_SIZE_MISMATCH    Real psVector size, %d, and imaginary psVector size, %d, must be the same.
+psVectorFFT_NONREAL_NOTSUPPORTED       Input psVector type, %s, is required to be either psF32 or psF64.
+psVectorFFT_NONCOMPLEX_NOTSUPPORTED    Input psVector type, %s, is required to be either psC32 or psC64.
+psVectorFFT_DIRECTION_NOTSET           Must specify the direction as either PS_FFT_FORWARD or PS_FFT_REVERSE.
Index: /branches/rel3/psLib/src/dataManip/psDataManipErrors.h
===================================================================
--- /branches/rel3/psLib/src/dataManip/psDataManipErrors.h	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/psDataManipErrors.h	(revision 2163)
@@ -0,0 +1,44 @@
+/** @file  psDataManipErrors.h
+ *
+ *  @brief Contains the error text for the data manipulation functions
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-13 20:46:57 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_DATAMANIP_ERRORS_H
+#define PS_DATAMANIP_ERRORS_H
+
+/* N.B., lines between '//~Start' and '//~End' are automatic generated from
+ * the template following the '//~Start'.  The template is used to generate
+ * the other lines by, for each error text in psDataManipErrors.dat, the following
+ * substitutions are made:
+ *     $1  The error text macro name (first word in the psDataManipErrors.dat lines)
+ *     $2  The error text (rest of the line in psDataManipErrors.dat)
+ *     $n  The order of the source line in psDataManipErrors.dat (comments excluded)
+ * 
+ * DO NOT EDIT THE LINES BETWEEN //~Start and //~End!  ANY CHANGES WILL BE OVERWRITTEN.
+ */
+
+#define PS_ERRORNAME_DOMAIN "psLib.dataManip."
+
+//~Start #define PS_ERRORTEXT_$1 "$2"
+#define PS_ERRORTEXT_psVectorFFT_IMAGE_TYPE_UNSUPPORTED "Input psVector type, %s, is not supported. Valid data types are psF32 and psC32."
+#define PS_ERRORTEXT_psVectorFFT_REVERSE_NOT_COMPLEX "Input psVector (%s) is not complex.  Reverse FFT operation requires a complex input."
+#define PS_ERRORTEXT_psVectorFFT_FORWARD_NOT_REAL "Input psVector (%s) is not real.  Forward FFT operation requires a real input."
+#define PS_ERRORTEXT_psVectorFFT_FFTW_PLAN_NULL "Could not create a valid FFT plan to perform the transform."
+#define PS_ERRORTEXT_psVectorFFT_TYPE_UNSUPPORTED "Specified psVector type, %s, is not supported."
+#define PS_ERRORTEXT_psVectorFFT_REAL_IMAG_TYPE_MISMATCH "Real psVector type, %s, and imaginary psVector type, %s, must be the same."
+#define PS_ERRORTEXT_psVectorFFT_REAL_IMAG_SIZE_MISMATCH "Real psVector size, %d, and imaginary psVector size, %d, must be the same."
+#define PS_ERRORTEXT_psVectorFFT_NONREAL_NOTSUPPORTED "Input psVector type, %s, is required to be either psF32 or psF64."
+#define PS_ERRORTEXT_psVectorFFT_NONCOMPLEX_NOTSUPPORTED "Input psVector type, %s, is required to be either psC32 or psC64."
+#define PS_ERRORTEXT_psVectorFFT_DIRECTION_NOTSET "Must specify the direction as either PS_FFT_FORWARD or PS_FFT_REVERSE."
+//~End
+
+#endif
Index: /branches/rel3/psLib/src/dataManip/psFunctions.c
===================================================================
--- /branches/rel3/psLib/src/dataManip/psFunctions.c	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/psFunctions.c	(revision 2163)
@@ -0,0 +1,2111 @@
+/** @file  psFunctions.c
+ *
+ *  @brief Contains basic function allocation, deallocation, and evaluation
+ *         routines.
+ *
+ *  This file will hold the functions for allocated, freeing, and evaluating
+ *  polynomials.  It also contains a Gaussian functions.
+ *
+ *  @version $Revision: 1.52 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 01:44:48 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+/*****************************************************************************/
+/*  INCLUDE FILES                                                            */
+/*****************************************************************************/
+#include <gsl/gsl_rng.h>
+#include <gsl/gsl_randist.h>
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <float.h>
+#include <math.h>
+
+#include "psMemory.h"
+#include "psVector.h"
+#include "psScalar.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psLogMsg.h"
+
+#include "psFunctions.h"
+/*****************************************************************************/
+/* DEFINE STATEMENTS                                                         */
+/*****************************************************************************/
+/*
+ * The following macros take the vector IN as input.  If IN is not of
+ * the correct type, then a new vector OUT is created of the correct
+ * type, and the elements of IN and converted to OUT.
+ *
+ * If vector IN is the correct type, then OUT is simply set to IN.
+ */
+#define PS_CONVERT_VECTOR_F32(IN, OUT) \
+if (IN->type.type != PS_TYPE_F32) { \
+    psLogMsg(__func__, PS_LOG_WARN, \
+             "Input vector has incorrect type (%d).\n", \
+             IN->type); \
+    OUT = psVectorAlloc(IN->n, PS_TYPE_F32); \
+    \
+    if (IN->type.type == PS_TYPE_F64) { \
+        for (int i=0;i<IN->n;i++) { \
+            OUT->data.F32[i] = (float) (IN->data.F64[i]); \
+        } \
+    }\
+    else { \
+        psAbort(__func__, "Wrong type.\n"); \
+    } \
+} else { \
+    OUT = (psVector *) IN; \
+}
+
+#define PS_CONVERT_VECTOR_F64(IN, OUT) \
+if (IN->type.type != PS_TYPE_F64) { \
+    psLogMsg(__func__, PS_LOG_WARN, \
+             "Input vector has incorrect type (%d).\n", \
+             IN->type); \
+    OUT = psVectorAlloc(IN->n, PS_TYPE_F64); \
+    \
+    if (IN->type.type == PS_TYPE_F32) { \
+        for (int i=0;i<IN->n;i++) { \
+            OUT->data.F64[i] = (float) (IN->data.F32[i]); \
+        } \
+    }\
+    else { \
+        psAbort(__func__, "Wrong type.\n"); \
+    } \
+} else { \
+    OUT = (psVector *) IN; \
+}
+
+/*****************************************************************************/
+/* TYPE DEFINITIONS                                                          */
+/*****************************************************************************/
+static void polynomial1DFree(psPolynomial1D* myPoly);
+static void polynomial2DFree(psPolynomial2D* myPoly);
+static void polynomial3DFree(psPolynomial3D* myPoly);
+static void polynomial4DFree(psPolynomial4D* myPoly);
+static void dPolynomial1DFree(psDPolynomial1D* myPoly);
+static void dPolynomial2DFree(psDPolynomial2D* myPoly);
+static void dPolynomial3DFree(psDPolynomial3D* myPoly);
+static void dPolynomial4DFree(psDPolynomial4D* myPoly);
+
+/*****************************************************************************/
+/* GLOBAL VARIABLES                                                          */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FILE STATIC VARIABLES                                                     */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - LOCAL                                           */
+/*****************************************************************************/
+
+/*****************************************************************************
+CreateChebyshevPolys(n): this routine takes as input the required order n,
+and returns as output as a pointer to an array of n psPolynomial1D
+structures, corresponding to the first n Chebyshev polynomials.
+ 
+XXX: The output should be static since the Chebyshev polynomials might be
+used frequently and the data structure created here does not contain the
+outer coefficients of the Chebyshev polynomials.
+ *****************************************************************************/
+static psPolynomial1D **CreateChebyshevPolys(int maxChebyPoly)
+{
+    psPolynomial1D **chebPolys = NULL;
+    int i = 0;
+    int j = 0;
+
+    chebPolys = (psPolynomial1D **) psAlloc(maxChebyPoly * sizeof(psPolynomial1D *));
+    for (i = 0; i < maxChebyPoly; i++) {
+        chebPolys[i] = psPolynomial1DAlloc(i + 1, PS_POLYNOMIAL_ORD);
+    }
+
+    // Create the Chebyshev polynomials.
+    // Polynomial i has i-th order.
+    chebPolys[0]->coeff[0] = 1;
+    chebPolys[1]->coeff[1] = 1;
+    for (i = 2; i < maxChebyPoly; i++) {
+        for (j = 0; j < chebPolys[i - 1]->n; j++) {
+            chebPolys[i]->coeff[j + 1] = 2 * chebPolys[i - 1]->coeff[j];
+        }
+        for (j = 0; j < chebPolys[i - 2]->n; j++) {
+            chebPolys[i]->coeff[j] -= chebPolys[i - 2]->coeff[j];
+        }
+    }
+
+    return (chebPolys);
+}
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - PUBLIC                                         */
+/*****************************************************************************/
+
+/*****************************************************************************
+    Evaluate a non-normalized Gaussian with the given mean and sigma at the
+    given coordianate.  Note that this is not a Gaussian deviate.  The
+    evaluated Gaussian is: \f[ exp(-\frac{(x-mean)^2}{2\sigma^2}) \f]
+ *****************************************************************************/
+float psGaussian(float x, float mean, float sigma, bool normal)
+{
+    float tmp = 1.0;
+
+    psTrace(".psLib.dataManip.psFunctions.psGaussian", 4,
+            "---- psGaussian() begin ----\n");
+
+    if (normal == true) {
+        #ifdef DARWIN
+        tmp = 1.0 / (float)sqrt(2.0 * M_PI * (sigma * sigma));
+        #else
+
+        tmp = 1.0 / sqrtf(2.0 * M_PI * (sigma * sigma));
+        #endif
+
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.psGaussian", 4,
+            "---- psGaussian() end ----\n");
+    return(tmp * exp(-((x - mean) * (x - mean)) / (2.0 * sigma * sigma)));
+}
+
+/*****************************************************************************
+    psGaussianDev()
+ This routine creates a psVector of the specified size and type F32
+ and fills it with a random Gaussian distribution of numbers with
+ the specified mean and sigma.  This routine makes use of the GSL
+ routines for generating both uniformly distributed numbers and the
+ Gaussian distribution as well.
+ 
+ NOTE: XXX: There is no way to seed the random generator.
+ *****************************************************************************/
+psVector* psGaussianDev(float mean, float sigma, int Npts)
+{
+    psVector* gauss = NULL;
+    const gsl_rng_type *T = NULL;
+    gsl_rng *r = NULL;
+    int i = 0;
+
+    gauss = psVectorAlloc(Npts, PS_TYPE_F32);
+    gauss->n = Npts;
+    gsl_rng_env_setup();
+    T = gsl_rng_default;
+    r = gsl_rng_alloc(T);
+
+    for (i = 0; i < Npts; i++) {
+        gauss->data.F32[i] = mean + gsl_ran_gaussian(r, sigma);
+    }
+
+    // NOTE: Should I free r as well?
+    return(gauss);
+}
+
+/*****************************************************************************
+    This routine must allocate memory for the polynomial structures.
+ *****************************************************************************/
+psPolynomial1D* psPolynomial1DAlloc(int n,
+                                    psPolynomialType type)
+{
+    int i = 0;
+    psPolynomial1D* newPoly = NULL;
+
+    newPoly = (psPolynomial1D* ) psAlloc(sizeof(psPolynomial1D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) polynomial1DFree);
+
+    newPoly->type = type;
+    newPoly->n = n;
+    newPoly->coeff = (float *)psAlloc(n * sizeof(float));
+    newPoly->coeffErr = (float *)psAlloc(n * sizeof(float));
+    newPoly->mask = (char *)psAlloc(n * sizeof(char));
+    for (i = 0; i < n; i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0;
+    }
+
+    return(newPoly);
+}
+
+psPolynomial2D* psPolynomial2DAlloc(int nX, int nY,
+                                    psPolynomialType type)
+{
+    int x = 0;
+    int y = 0;
+    psPolynomial2D* newPoly = NULL;
+
+    newPoly = (psPolynomial2D* ) psAlloc(sizeof(psPolynomial2D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) polynomial2DFree);
+
+    newPoly->type = type;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+
+    newPoly->coeff = (float **)psAlloc(nX * sizeof(float *));
+    newPoly->coeffErr = (float **)psAlloc(nX * sizeof(float *));
+    newPoly->mask = (char **)psAlloc(nX * sizeof(char *));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (float *)psAlloc(nY * sizeof(float));
+        newPoly->coeffErr[x] = (float *)psAlloc(nY * sizeof(float));
+        newPoly->mask[x] = (char *)psAlloc(nY * sizeof(char));
+    }
+    for (x = 0; x < nX; x++) {
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = 0.0;
+            newPoly->coeffErr[x][y] = 0.0;
+            newPoly->mask[x][y] = 0;
+        }
+    }
+
+    return(newPoly);
+}
+
+psPolynomial3D* psPolynomial3DAlloc(int nX, int nY, int nZ,
+                                    psPolynomialType type)
+{
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psPolynomial3D* newPoly = NULL;
+
+    newPoly = (psPolynomial3D* ) psAlloc(sizeof(psPolynomial3D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) polynomial3DFree);
+
+    newPoly->type = type;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff = (float ***)psAlloc(nX * sizeof(float **));
+    newPoly->coeffErr = (float ***)psAlloc(nX * sizeof(float **));
+    newPoly->mask = (char ***)psAlloc(nX * sizeof(char **));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (float **)psAlloc(nY * sizeof(float *));
+        newPoly->coeffErr[x] = (float **)psAlloc(nY * sizeof(float *));
+        newPoly->mask[x] = (char **)psAlloc(nY * sizeof(char *));
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = (float *)psAlloc(nZ * sizeof(float));
+            newPoly->coeffErr[x][y] = (float *)psAlloc(nZ * sizeof(float));
+            newPoly->mask[x][y] = (char *)psAlloc(nZ * sizeof(char));
+        }
+    }
+    for (x = 0; x < nX; x++) {
+        for (y = 0; y < nY; y++) {
+            for (z = 0; z < nZ; z++) {
+                newPoly->coeff[x][y][z] = 0.0;
+                newPoly->coeffErr[x][y][z] = 0.0;
+                newPoly->mask[x][y][z] = 0;
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+psPolynomial4D* psPolynomial4DAlloc(int nW, int nX, int nY, int nZ,
+                                    psPolynomialType type)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psPolynomial4D* newPoly = NULL;
+
+    newPoly = (psPolynomial4D* ) psAlloc(sizeof(psPolynomial4D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) polynomial4DFree);
+
+    newPoly->type = type;
+    newPoly->nW = nW;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff = (float ****)psAlloc(nW * sizeof(float ***));
+    newPoly->coeffErr = (float ****)psAlloc(nW * sizeof(float ***));
+    newPoly->mask = (char ****)psAlloc(nW * sizeof(char ***));
+    for (w = 0; w < nW; w++) {
+        newPoly->coeff[w] = (float ***)psAlloc(nX * sizeof(float **));
+        newPoly->coeffErr[w] = (float ***)psAlloc(nX * sizeof(float **));
+        newPoly->mask[w] = (char ***)psAlloc(nX * sizeof(char **));
+        for (x = 0; x < nX; x++) {
+            newPoly->coeff[w][x] = (float **)psAlloc(nY * sizeof(float *));
+            newPoly->coeffErr[w][x] = (float **)psAlloc(nY * sizeof(float *));
+            newPoly->mask[w][x] = (char **)psAlloc(nY * sizeof(char *));
+            for (y = 0; y < nY; y++) {
+                newPoly->coeff[w][x][y] = (float *)psAlloc(nZ * sizeof(float));
+                newPoly->coeffErr[w][x][y] = (float *)psAlloc(nZ * sizeof(float));
+                newPoly->mask[w][x][y] = (char *)psAlloc(nZ * sizeof(char));
+            }
+        }
+    }
+    for (w = 0; w < nW; w++) {
+        for (x = 0; x < nX; x++) {
+            for (y = 0; y < nY; y++) {
+                for (z = 0; z < nZ; z++) {
+                    newPoly->coeff[w][x][y][z] = 0.0;
+                    newPoly->coeffErr[w][x][y][z] = 0.0;
+                    newPoly->mask[w][x][y][z] = 0;
+                }
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+static void polynomial1DFree(psPolynomial1D* myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void polynomial2DFree(psPolynomial2D* myPoly)
+{
+    int x = 0;
+
+    for (x = 0; x < myPoly->nX; x++) {
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void polynomial3DFree(psPolynomial3D* myPoly)
+{
+    int x = 0;
+    int y = 0;
+
+    for (x = 0; x < myPoly->nX; x++) {
+        for (y = 0; y < myPoly->nY; y++) {
+            psFree(myPoly->coeff[x][y]);
+            psFree(myPoly->coeffErr[x][y]);
+            psFree(myPoly->mask[x][y]);
+        }
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void polynomial4DFree(psPolynomial4D* myPoly)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+
+    for (w = 0; w < myPoly->nW; w++) {
+        for (x = 0; x < myPoly->nX; x++) {
+            for (y = 0; y < myPoly->nY; y++) {
+                psFree(myPoly->coeff[w][x][y]);
+                psFree(myPoly->coeffErr[w][x][y]);
+                psFree(myPoly->mask[w][x][y]);
+            }
+            psFree(myPoly->coeff[w][x]);
+            psFree(myPoly->coeffErr[w][x]);
+            psFree(myPoly->mask[w][x]);
+        }
+        psFree(myPoly->coeff[w]);
+        psFree(myPoly->coeffErr[w]);
+        psFree(myPoly->mask[w]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ 
+    XXX: Should the "coeffErr[]" should be used as well?
+ *****************************************************************************/
+float p_psOrdPolynomial1DEval(float x, const psPolynomial1D* myPoly)
+{
+    int loop_x = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+
+    psTrace(".psLib.dataManip.psFunctions.p_psOrdPolynomial1DEval", 4,
+            "---- Calling p_psOrdPolynomial1DEval(%f)\n", x);
+    psTrace(".psLib.dataManip.psFunctions.p_psOrdPolynomial1DEval", 4,
+            "Polynomial order is %d\n", myPoly->n);
+    for (loop_x = 0; loop_x < myPoly->n; loop_x++) {
+        psTrace(".psLib.dataManip.psFunctions.p_psOrdPolynomial1DEval", 4,
+                "Polynomial coeff[%d] is %f\n", loop_x, myPoly->coeff[loop_x]);
+    }
+
+
+    if (NULL == myPoly) {
+        psAbort(__func__, "psPolynomial1DEval(): myPoly is NULL\n");
+    }
+
+    // NOTE: Do we want to flag this case?
+    if (myPoly->n == 0) {
+        return(1.0);
+    }
+
+    if (NULL == myPoly->coeff) {
+        psAbort(__func__, "psPolynomial1DEval(): myPoly->coeff is NULL\n");
+    }
+
+    for (loop_x = 0; loop_x < myPoly->n; loop_x++) {
+        if (myPoly->mask[loop_x] == 0) {
+            psTrace(".psLib.dataManip.psFunctions.p_psOrdPolynomial1DEval", 10,
+                    "polysum+= sum*coeff [%f+= (%f * %f)\n", polySum, xSum, myPoly->coeff[loop_x]);
+            polySum += xSum * myPoly->coeff[loop_x];
+            xSum *= x;
+        }
+    }
+
+    return(polySum);
+}
+
+// XXX: You can do this without having to psAlloc() vector d.
+// XXX: How does the mask vector effect Crenshaw's formula?
+float p_psChebPolynomial1DEval(float x, const psPolynomial1D* myPoly)
+{
+    psVector *d;
+    int n;
+    int i;
+    float tmp;
+
+    n = myPoly->n;
+    d = psVectorAlloc(n, PS_TYPE_F32);
+    d->data.F32[n-1] = myPoly->coeff[n-1];
+    d->data.F32[n-2] = (2.0 * x * d->data.F32[n-1]) + myPoly->coeff[n-2];
+    for (i=n-3;i>=1;i--) {
+        d->data.F32[i] = (2.0 * x * d->data.F32[i+1]) -
+                         (d->data.F32[i+2]) +
+                         (myPoly->coeff[i]);
+    }
+
+    tmp = (x * d->data.F32[1]) -
+          (d->data.F32[2]) +
+          (0.5 * myPoly->coeff[0]);
+
+    psFree(d);
+    return(tmp);
+    /*
+
+    int n;
+    int i;
+    float tmp;
+    psPolynomial1D **chebPolys = NULL;
+
+    n = myPoly->n;
+    chebPolys = CreateChebyshevPolys(n);
+
+    tmp = 0.0;
+    for (i=0;i<myPoly->n;i++) {
+        tmp+= (myPoly->coeff[i] * psPolynomial1DEval(x, chebPolys[i]));
+        //            printf("HMMM: psPolynomial1DEval(%f, chebPolys[%d]) is %f\n", x, i, psPolynomial1DEval(x, chebPolys[i]));
+    }
+    tmp-= (myPoly->coeff[0]/2.0);
+
+
+    return(tmp);
+    */
+}
+
+float psPolynomial1DEval(float x, const psPolynomial1D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psOrdPolynomial1DEval(x, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psChebPolynomial1DEval(x, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psPolynomial1DEvalVector(const psVector *x,
+                                   const psPolynomial1D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    int i;
+
+    PS_CONVERT_VECTOR_F32(x, myX);
+
+    tmp = psVectorAlloc(x->n, PS_TYPE_F32);
+    for (i=0;i<x->n;i++) {
+        tmp->data.F32[i] = psPolynomial1DEval(x->data.F32[i], myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    return(tmp);
+}
+
+
+float p_psOrdPolynomial2DEval(float x, float y, const psPolynomial2D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        ySum = xSum;
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            if (myPoly->mask[loop_x][loop_y] == 0) {
+                polySum += ySum * myPoly->coeff[loop_x][loop_y];
+                ySum *= y;
+            }
+        }
+        xSum *= x;
+    }
+
+    return(polySum);
+}
+
+float p_psChebPolynomial2DEval(float x, float y, const psPolynomial2D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int i = 0;
+    float polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nX;
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            if (myPoly->mask[loop_x][loop_y] == 0) {
+                polySum += myPoly->coeff[loop_x][loop_y] *
+                           psPolynomial1DEval(x, chebPolys[loop_x]) *
+                           psPolynomial1DEval(y, chebPolys[loop_y]);
+            }
+        }
+    }
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+float psPolynomial2DEval(float x, float y, const psPolynomial2D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psOrdPolynomial2DEval(x, y, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psChebPolynomial2DEval(x, y, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+
+psVector *psPolynomial2DEvalVector(const psVector *x,
+                                   const psVector *y,
+                                   const psPolynomial2D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F32(x, myX);
+    PS_CONVERT_VECTOR_F32(y, myY);
+    vecLen=x->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F32);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F32[i] = psPolynomial2DEval(myX->data.F32[i],
+                                              myY->data.F32[i],
+                                              myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F32) {
+        psFree(myY);
+    }
+    return(tmp);
+}
+
+
+
+float p_psOrdPolynomial3DEval(float x, float y, float z, const psPolynomial3D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+    float zSum = 1.0;
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        ySum = xSum;
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            zSum = ySum;
+            for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                if (myPoly->mask[loop_x][loop_y][loop_z] == 0) {
+                    polySum += zSum * myPoly->coeff[loop_x][loop_y][loop_z];
+                    zSum *= z;
+                }
+            }
+            ySum *= y;
+        }
+        xSum *= x;
+    }
+
+    return(polySum);
+}
+
+float p_psChebPolynomial3DEval(float x, float y, float z, const psPolynomial3D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    int i = 0;
+    float polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nX;
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    if (myPoly->nZ > maxChebyPoly) {
+        maxChebyPoly = myPoly->nZ;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                if (myPoly->mask[loop_x][loop_y][loop_z] == 0) {
+                    polySum += myPoly->coeff[loop_x][loop_y][loop_z] *
+                               psPolynomial1DEval(x, chebPolys[loop_x]) *
+                               psPolynomial1DEval(y, chebPolys[loop_y]) *
+                               psPolynomial1DEval(z, chebPolys[loop_z]);
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+float psPolynomial3DEval(float x, float y, float z, const psPolynomial3D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psOrdPolynomial3DEval(x, y, z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psChebPolynomial3DEval(x, y, z, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psPolynomial3DEvalVector(const psVector *x,
+                                   const psVector *y,
+                                   const psVector *z,
+                                   const psPolynomial3D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F32(x, myX);
+    PS_CONVERT_VECTOR_F32(y, myY);
+    PS_CONVERT_VECTOR_F32(z, myZ);
+    vecLen=x->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+    if (z->n < vecLen) {
+        vecLen = z->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F32);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F32[i] = psPolynomial3DEval(myX->data.F32[i],
+                                              myY->data.F32[i],
+                                              myZ->data.F32[i],
+                                              myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F32) {
+        psFree(myY);
+    }
+    if (z->type.type != PS_TYPE_F32) {
+        psFree(myZ);
+    }
+    return(tmp);
+}
+
+
+
+
+
+
+float p_psOrdPolynomial4DEval(float w, float x, float y, float z, const psPolynomial4D* myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    float polySum = 0.0;
+    float wSum = 1.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+    float zSum = 1.0;
+
+    for (loop_w = 0; loop_w < myPoly->nW; loop_w++) {
+        xSum = wSum;
+        for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+            ySum = xSum;
+            for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+                zSum = ySum;
+                for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                    if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) {
+                        polySum += zSum * myPoly->coeff[loop_w][loop_x][loop_y][loop_z];
+                        zSum *= z;
+                    }
+                }
+                ySum *= y;
+            }
+            xSum *= x;
+        }
+        wSum *= w;
+    }
+
+    return(polySum);
+}
+
+float p_psChebPolynomial4DEval(float w, float x, float y, float z, const psPolynomial4D* myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    int i = 0;
+    float polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nW;
+    if (myPoly->nX > maxChebyPoly) {
+        maxChebyPoly = myPoly->nX;
+    }
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    if (myPoly->nZ > maxChebyPoly) {
+        maxChebyPoly = myPoly->nZ;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_w = 0; loop_w < myPoly->nW; loop_w++) {
+        for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+            for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+                for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                    if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) {
+                        polySum += myPoly->coeff[loop_w][loop_x][loop_y][loop_z] *
+                                   psPolynomial1DEval(w, chebPolys[loop_w]) *
+                                   psPolynomial1DEval(x, chebPolys[loop_x]) *
+                                   psPolynomial1DEval(y, chebPolys[loop_y]) *
+                                   psPolynomial1DEval(z, chebPolys[loop_z]);
+                    }
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+float psPolynomial4DEval(float w, float x, float y, float z, const psPolynomial4D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psOrdPolynomial4DEval(w,x,y,z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psChebPolynomial4DEval(w,x,y,z, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psPolynomial4DEvalVector(const psVector *w,
+                                   const psVector *x,
+                                   const psVector *y,
+                                   const psVector *z,
+                                   const psPolynomial4D *myPoly)
+{
+    psVector *tmp;
+    psVector *myW;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F32(w, myW);
+    PS_CONVERT_VECTOR_F32(x, myX);
+    PS_CONVERT_VECTOR_F32(y, myY);
+    PS_CONVERT_VECTOR_F32(z, myZ);
+    vecLen=w->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+    if (x->n < vecLen) {
+        vecLen = x->n;
+    }
+    if (z->n < vecLen) {
+        vecLen = z->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F32);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F32[i] = psPolynomial4DEval(myW->data.F32[i],
+                                              myX->data.F32[i],
+                                              myY->data.F32[i],
+                                              myZ->data.F32[i],
+                                              myPoly);
+    }
+
+    if (w->type.type != PS_TYPE_F32) {
+        psFree(myW);
+    }
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F32) {
+        psFree(myY);
+    }
+    if (z->type.type != PS_TYPE_F32) {
+        psFree(myZ);
+    }
+    return(tmp);
+}
+
+
+
+
+
+psDPolynomial1D* psDPolynomial1DAlloc(int n,
+                                      psPolynomialType type)
+{
+    int i = 0;
+    psDPolynomial1D* newPoly = NULL;
+
+    newPoly = (psDPolynomial1D* ) psAlloc(sizeof(psDPolynomial1D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) dPolynomial1DFree);
+
+    newPoly->type = type;
+    newPoly->n = n;
+    newPoly->coeff = (double *)psAlloc(n * sizeof(double));
+    newPoly->coeffErr = (double *)psAlloc(n * sizeof(double));
+    newPoly->mask = (char *)psAlloc(n * sizeof(char));
+    for (i = 0; i < n; i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0;
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial2D* psDPolynomial2DAlloc(int nX, int nY,
+                                      psPolynomialType type)
+{
+    int x = 0;
+    int y = 0;
+    psDPolynomial2D* newPoly = NULL;
+
+    newPoly = (psDPolynomial2D* ) psAlloc(sizeof(psDPolynomial2D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) dPolynomial2DFree);
+
+    newPoly->type = type;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+
+    newPoly->coeff = (double **)psAlloc(nX * sizeof(double *));
+    newPoly->coeffErr = (double **)psAlloc(nX * sizeof(double *));
+    newPoly->mask = (char **)psAlloc(nX * sizeof(char *));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (double *)psAlloc(nY * sizeof(double));
+        newPoly->coeffErr[x] = (double *)psAlloc(nY * sizeof(double));
+        newPoly->mask[x] = (char *)psAlloc(nY * sizeof(char));
+    }
+    for (x = 0; x < nX; x++) {
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = 0.0;
+            newPoly->coeffErr[x][y] = 0.0;
+            newPoly->mask[x][y] = 0;
+        }
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial3D* psDPolynomial3DAlloc(int nX, int nY, int nZ,
+                                      psPolynomialType type)
+{
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psDPolynomial3D* newPoly = NULL;
+
+    newPoly = (psDPolynomial3D* ) psAlloc(sizeof(psDPolynomial3D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) dPolynomial3DFree);
+
+    newPoly->type = type;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff = (double ***)psAlloc(nX * sizeof(double **));
+    newPoly->coeffErr = (double ***)psAlloc(nX * sizeof(double **));
+    newPoly->mask = (char ***)psAlloc(nX * sizeof(char **));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (double **)psAlloc(nY * sizeof(double *));
+        newPoly->coeffErr[x] = (double **)psAlloc(nY * sizeof(double *));
+        newPoly->mask[x] = (char **)psAlloc(nY * sizeof(char *));
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = (double *)psAlloc(nZ * sizeof(double));
+            newPoly->coeffErr[x][y] = (double *)psAlloc(nZ * sizeof(double));
+            newPoly->mask[x][y] = (char *)psAlloc(nZ * sizeof(char));
+        }
+    }
+    for (x = 0; x < nX; x++) {
+        for (y = 0; y < nY; y++) {
+            for (z = 0; z < nZ; z++) {
+                newPoly->coeff[x][y][z] = 0.0;
+                newPoly->coeffErr[x][y][z] = 0.0;
+                newPoly->mask[x][y][z] = 0;
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial4D* psDPolynomial4DAlloc(int nW, int nX, int nY, int nZ,
+                                      psPolynomialType type)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psDPolynomial4D* newPoly = NULL;
+
+    newPoly = (psDPolynomial4D* ) psAlloc(sizeof(psDPolynomial4D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) dPolynomial4DFree);
+
+    newPoly->type = type;
+    newPoly->nW = nW;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff = (double ****)psAlloc(nW * sizeof(double ***));
+    newPoly->coeffErr = (double ****)psAlloc(nW * sizeof(double ***));
+    newPoly->mask = (char ****)psAlloc(nW * sizeof(char ***));
+    for (w = 0; w < nW; w++) {
+        newPoly->coeff[w] = (double ***)psAlloc(nX * sizeof(double **));
+        newPoly->coeffErr[w] = (double ***)psAlloc(nX * sizeof(double **));
+        newPoly->mask[w] = (char ***)psAlloc(nX * sizeof(char **));
+        for (x = 0; x < nX; x++) {
+            newPoly->coeff[w][x] = (double **)psAlloc(nY * sizeof(double *));
+            newPoly->coeffErr[w][x] = (double **)psAlloc(nY * sizeof(double *));
+            newPoly->mask[w][x] = (char **)psAlloc(nY * sizeof(char *));
+            for (y = 0; y < nY; y++) {
+                newPoly->coeff[w][x][y] = (double *)psAlloc(nZ * sizeof(double));
+                newPoly->coeffErr[w][x][y] = (double *)psAlloc(nZ * sizeof(double));
+                newPoly->mask[w][x][y] = (char *)psAlloc(nZ * sizeof(char));
+            }
+        }
+    }
+    for (w = 0; w < nW; w++) {
+        for (x = 0; x < nX; x++) {
+            for (y = 0; y < nY; y++) {
+                for (z = 0; z < nZ; z++) {
+                    newPoly->coeff[w][x][y][z] = 0.0;
+                    newPoly->coeffErr[w][x][y][z] = 0.0;
+                    newPoly->mask[w][x][y][z] = 0;
+                }
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+static void dPolynomial1DFree(psDPolynomial1D* myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void dPolynomial2DFree(psDPolynomial2D* myPoly)
+{
+    int x = 0;
+
+    for (x = 0; x < myPoly->nX; x++) {
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void dPolynomial3DFree(psDPolynomial3D* myPoly)
+{
+    int x = 0;
+    int y = 0;
+
+    for (x = 0; x < myPoly->nX; x++) {
+        for (y = 0; y < myPoly->nY; y++) {
+            psFree(myPoly->coeff[x][y]);
+            psFree(myPoly->coeffErr[x][y]);
+            psFree(myPoly->mask[x][y]);
+        }
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void dPolynomial4DFree(psDPolynomial4D* myPoly)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+
+    for (w = 0; w < myPoly->nW; w++) {
+        for (x = 0; x < myPoly->nX; x++) {
+            for (y = 0; y < myPoly->nY; y++) {
+                psFree(myPoly->coeff[w][x][y]);
+                psFree(myPoly->coeffErr[w][x][y]);
+                psFree(myPoly->mask[w][x][y]);
+            }
+            psFree(myPoly->coeff[w][x]);
+            psFree(myPoly->coeffErr[w][x]);
+            psFree(myPoly->mask[w][x]);
+        }
+        psFree(myPoly->coeff[w]);
+        psFree(myPoly->coeffErr[w]);
+        psFree(myPoly->mask[w]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ *****************************************************************************/
+double p_psDOrdPolynomial1DEval(double x, const psDPolynomial1D* myPoly)
+{
+    int loop_x = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+
+    // NOTE: Do we want to flag this case?
+    if (myPoly->n == 0) {
+        return(1.0);
+    }
+
+    for (loop_x = 0; loop_x < myPoly->n; loop_x++) {
+        if (myPoly->mask[loop_x] == 0) {
+            polySum += xSum * myPoly->coeff[loop_x];
+            xSum *= x;
+        }
+    }
+
+    return(polySum);
+}
+
+// XXX: You can do this without having to psAlloc() vector d.
+// XXX: How does the mask vector effect Crenshaw's formula?
+double p_psDChebPolynomial1DEval(double x, const psDPolynomial1D* myPoly)
+{
+    psVector *d;
+    int n;
+    int i;
+    double tmp;
+
+    n = myPoly->n;
+    d = psVectorAlloc(n, PS_TYPE_F64);
+    d->data.F64[n-1] = myPoly->coeff[n-1];
+    d->data.F64[n-2] = (2.0 * x * d->data.F64[n-1]) + myPoly->coeff[n-2];
+    for (i=n-3;i>=1;i--) {
+        d->data.F64[i] = (2.0 * x * d->data.F64[i+1]) -
+                         (d->data.F64[i+2]) +
+                         (myPoly->coeff[i]);
+    }
+
+    tmp = (x * d->data.F64[1]) -
+          (d->data.F64[2]) +
+          (0.5 * myPoly->coeff[0]);
+
+    psFree(d);
+    return(tmp);
+}
+
+double psDPolynomial1DEval(double x, const psDPolynomial1D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psDOrdPolynomial1DEval(x, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psDChebPolynomial1DEval(x, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psDPolynomial1DEvalVector(const psVector *x,
+                                    const psDPolynomial1D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    int i;
+
+    PS_CONVERT_VECTOR_F64(x, myX);
+
+    tmp = psVectorAlloc(x->n, PS_TYPE_F64);
+    for (i=0;i<x->n;i++) {
+        tmp->data.F64[i] = psDPolynomial1DEval(x->data.F64[i], myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    return(tmp);
+}
+
+
+
+double p_psDOrdPolynomial2DEval(double x, double y, const psDPolynomial2D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        ySum = xSum;
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            if (myPoly->mask[loop_x][loop_y] == 0) {
+                polySum += ySum * myPoly->coeff[loop_x][loop_y];
+                ySum *= y;
+            }
+        }
+        xSum *= x;
+    }
+
+    return(polySum);
+}
+
+double p_psDChebPolynomial2DEval(double x, double y, const psDPolynomial2D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int i = 0;
+    double polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nX;
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            if (myPoly->mask[loop_x][loop_y] == 0) {
+                polySum += myPoly->coeff[loop_x][loop_y] *
+                           psPolynomial1DEval(x, chebPolys[loop_x]) *
+                           psPolynomial1DEval(y, chebPolys[loop_y]);
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+double psDPolynomial2DEval(double x, double y, const psDPolynomial2D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psDOrdPolynomial2DEval(x, y, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psDChebPolynomial2DEval(x, y, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psDPolynomial2DEvalVector(const psVector *x,
+                                    const psVector *y,
+                                    const psDPolynomial2D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F64(x, myX);
+    PS_CONVERT_VECTOR_F64(y, myY);
+    vecLen=x->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F64);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F64[i] = psDPolynomial2DEval(myX->data.F64[i],
+                                               myY->data.F64[i],
+                                               myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F64) {
+        psFree(myY);
+    }
+    return(tmp);
+}
+
+
+
+double p_psDOrdPolynomial3DEval(double x, double y, double z, const psDPolynomial3D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+    double zSum = 1.0;
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        ySum = xSum;
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            zSum = ySum;
+            for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                if (myPoly->mask[loop_x][loop_y][loop_z] == 0) {
+                    polySum += zSum * myPoly->coeff[loop_x][loop_y][loop_z];
+                    zSum *= z;
+                }
+            }
+            ySum *= y;
+        }
+        xSum *= x;
+    }
+
+    return(polySum);
+}
+
+double p_psDChebPolynomial3DEval(double x, double y, double z, const psDPolynomial3D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    int i = 0;
+    double polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nX;
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    if (myPoly->nZ > maxChebyPoly) {
+        maxChebyPoly = myPoly->nZ;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                if (myPoly->mask[loop_x][loop_y][loop_z] == 0) {
+                    polySum += myPoly->coeff[loop_x][loop_y][loop_z] *
+                               psPolynomial1DEval(x, chebPolys[loop_x]) *
+                               psPolynomial1DEval(y, chebPolys[loop_y]) *
+                               psPolynomial1DEval(z, chebPolys[loop_z]);
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+double psDPolynomial3DEval(double x, double y, double z, const psDPolynomial3D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psDOrdPolynomial3DEval(x, y, z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psDChebPolynomial3DEval(x, y, z, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psDPolynomial3DEvalVector(const psVector *x,
+                                    const psVector *y,
+                                    const psVector *z,
+                                    const psDPolynomial3D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F64(x, myX);
+    PS_CONVERT_VECTOR_F64(y, myY);
+    PS_CONVERT_VECTOR_F64(z, myZ);
+    vecLen=x->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+    if (z->n < vecLen) {
+        vecLen = z->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F64);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F64[i] = psDPolynomial3DEval(myX->data.F64[i],
+                                               myY->data.F64[i],
+                                               myZ->data.F64[i],
+                                               myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F64) {
+        psFree(myY);
+    }
+    if (z->type.type != PS_TYPE_F64) {
+        psFree(myZ);
+    }
+    return(tmp);
+}
+
+
+
+
+
+
+
+
+double p_psDOrdPolynomial4DEval(double w, double x, double y, double z, const psDPolynomial4D* myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    double polySum = 0.0;
+    double wSum = 1.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+    double zSum = 1.0;
+
+    for (loop_w = 0; loop_w < myPoly->nW; loop_w++) {
+        xSum = wSum;
+        for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+            ySum = xSum;
+            for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+                zSum = ySum;
+                for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                    if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) {
+                        polySum += zSum * myPoly->coeff[loop_w][loop_x][loop_y][loop_z];
+                        zSum *= z;
+                    }
+                }
+                ySum *= y;
+            }
+            xSum *= x;
+        }
+        wSum *= w;
+    }
+
+    return(polySum);
+}
+
+double p_psDChebPolynomial4DEval(double w, double x, double y, double z, const psDPolynomial4D* myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    int i = 0;
+    double polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nW;
+    if (myPoly->nX > maxChebyPoly) {
+        maxChebyPoly = myPoly->nX;
+    }
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    if (myPoly->nZ > maxChebyPoly) {
+        maxChebyPoly = myPoly->nZ;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_w = 0; loop_w < myPoly->nW; loop_w++) {
+        for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+            for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+                for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                    if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) {
+                        polySum += myPoly->coeff[loop_w][loop_x][loop_y][loop_z] *
+                                   psPolynomial1DEval(w, chebPolys[loop_w]) *
+                                   psPolynomial1DEval(x, chebPolys[loop_x]) *
+                                   psPolynomial1DEval(y, chebPolys[loop_y]) *
+                                   psPolynomial1DEval(z, chebPolys[loop_z]);
+                    }
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+double psDPolynomial4DEval(double w, double x, double y, double z, const psDPolynomial4D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psDOrdPolynomial4DEval(w,x,y,z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psDChebPolynomial4DEval(w,x,y,z, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psDPolynomial4DEvalVector(const psVector *w,
+                                    const psVector *x,
+                                    const psVector *y,
+                                    const psVector *z,
+                                    const psDPolynomial4D *myPoly)
+{
+    psVector *tmp;
+    psVector *myW;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F64(w, myW);
+    PS_CONVERT_VECTOR_F64(x, myX);
+    PS_CONVERT_VECTOR_F64(y, myY);
+    PS_CONVERT_VECTOR_F64(z, myZ);
+    vecLen=w->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+    if (x->n < vecLen) {
+        vecLen = x->n;
+    }
+    if (z->n < vecLen) {
+        vecLen = z->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F64);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F64[i] = psDPolynomial4DEval(myW->data.F64[i],
+                                               myX->data.F64[i],
+                                               myY->data.F64[i],
+                                               myZ->data.F64[i],
+                                               myPoly);
+    }
+
+    if (w->type.type != PS_TYPE_F64) {
+        psFree(myW);
+    }
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F64) {
+        psFree(myY);
+    }
+    if (z->type.type != PS_TYPE_F64) {
+        psFree(myZ);
+    }
+    return(tmp);
+}
+
+
+
+
+//typedef struct {
+//    int n;
+//    psPolynomial1D **spline;
+//    float *p_psDeriv2;
+//    float *domains;
+//} psSpline1D;
+
+/*****************************************************************************
+    NOTE: "n" specifies the number of spline polynomials.  Therefore, there
+    must exist n+1 points in "domains".
+ 
+XXX: Ensure that domain[i+1] != domain[i]
+ *****************************************************************************/
+psSpline1D *psSpline1DAlloc(int numSplines,
+                            int order,
+                            float min,
+                            float max)
+{
+    psSpline1D *tmp = NULL;
+    int i;
+    float tmpDomain;
+    float width;
+
+    if (fabs(max-min) < FLT_EPSILON) {
+        psLogMsg(__func__, PS_LOG_WARN, "min and max are the same.\n");
+        return(NULL);
+    }
+
+    tmp = (psSpline1D *) psAlloc(sizeof(psSpline1D));
+    tmp->n = numSplines;
+
+    tmp->spline = (psPolynomial1D **) psAlloc(numSplines * sizeof(psPolynomial1D *));
+    for (i=0;i<numSplines;i++) {
+        (tmp->spline)[i] = psPolynomial1DAlloc(order+1, PS_POLYNOMIAL_ORD);
+    }
+
+    // This should be set by the psVectorFitSpline1D()
+    tmp->p_psDeriv2 = NULL;
+
+    tmp->domains = (float *) psAlloc((numSplines+1) * sizeof(float));
+    width = (max - min) / ((float) numSplines);
+
+    (tmp->domains)[0] = min;
+    tmpDomain = min+width;
+    for (i=1;i<numSplines+1;i++) {
+        (tmp->domains)[i] = tmpDomain;
+        tmpDomain+= width;
+    }
+    (tmp->domains)[numSplines] = max;
+
+    return(tmp);
+}
+
+// XXX: Have Robert put the dealocator in the memory file.
+int p_psSpline1DFree(psSpline1D *tmpSpline)
+{
+    int i;
+
+    if (tmpSpline == NULL) {
+        return(0);
+    }
+
+    if (tmpSpline->spline != NULL) {
+        for (i=0;i<tmpSpline->n;i++) {
+            psFree((tmpSpline->spline)[i]);
+        }
+        psFree(tmpSpline->spline);
+    }
+
+    if (tmpSpline->p_psDeriv2 != NULL) {
+        psFree(tmpSpline->p_psDeriv2);
+    }
+    psFree(tmpSpline->domains);
+    psFree(tmpSpline);
+
+    return(0);
+}
+
+/*****************************************************************************
+ *****************************************************************************/
+psSpline1D *psSpline1DAllocGeneric(const psVector *bounds,
+                                   int order)
+{
+    psSpline1D *tmp = NULL;
+    int i;
+    int numSplines;
+
+    tmp = (psSpline1D *) psAlloc(sizeof(psSpline1D));
+
+    numSplines = bounds->n - 1;
+    tmp->n = numSplines;
+
+    tmp->spline = (psPolynomial1D **) psAlloc(numSplines * sizeof(psPolynomial1D *));
+    for (i=0;i<numSplines;i++) {
+        (tmp->spline)[i] = psPolynomial1DAlloc(order+1, PS_POLYNOMIAL_ORD);
+    }
+
+    tmp->domains = (float *) psAlloc((bounds->n) * sizeof(float));
+
+    for (i=0;i<bounds->n;i++) {
+        (tmp->domains)[i] = bounds->data.F32[i];
+        if (i<(bounds->n-1)) {
+            if (FLT_EPSILON < fabs(bounds->data.F32[i+1]-bounds->data.F32[i])) {
+                // XXX: psErrorMsg(data points must be distinct)
+            }
+        }
+    }
+
+    return(tmp);
+}
+
+/*****************************************************************************
+p_psVectorBinDisectF32(): This is a private function which takes as input a
+vector of floating point data as well as a single floating point values.
+The input vector values are assumed to be non-decreasing (v[i-1] <= v[j] for
+all j>=i).  This routine does a binary disection of the vector and returns
+"i" such that (v[i] <= x <= v[i+1).  If x lies outside the range of v[],
+then this routine prints a warning message and returns (-2 or -1).
+ 
+XXX: Macro this for a few different types.
+ 
+XXX: name since we don't take psVectors as input.
+ *****************************************************************************/
+int p_psVectorBinDisectF32(float *bins,
+                           int numBins,
+                           float x)
+{
+    int min;
+    int max;
+    int mid;
+
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectF32", 4,
+            "---- Calling p_psVectorBinDisectF32(%f)\n", x);
+
+    if (x < bins[0]) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "p_psVectorBinDisectF32(): ordinate %f is outside vector range (%f - %f).",
+                 x, bins[0], bins[numBins-1]);
+        return(-2);
+    }
+
+    if (x > bins[numBins-1]) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "p_psVectorBinDisectF32(): ordinate %f is outside vector range (%f - %f).",
+                 x, bins[0], bins[numBins-1]);
+        return(-1);
+    }
+
+    min = 0;
+    max = numBins-2;
+    mid = ((max+1)-min)/2;
+
+    while (min != max) {
+        psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectF32", 4,
+                "(min, mid, max) is (%d, %d, %d): (x, bins) is (%f, %f)\n",
+                min, mid, max, x, bins[mid]);
+
+        if (x == bins[mid]) {
+            psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectF32", 4,
+                    "---- Exiting p_psVectorBinDisectF32(): bin %d\n", mid);
+            return(mid);
+        } else if (x < bins[mid]) {
+            max = mid-1;
+        } else {
+            min = mid;
+        }
+        mid = ((max+1)+min)/2;
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectF32", 4,
+            "---- Exiting p_psVectorBinDisectF32(): bin %d\n", min);
+    return(min);
+}
+
+/*****************************************************************************
+p_psVectorBinDisectS32(): integer version of above.
+ *****************************************************************************/
+int p_psVectorBinDisectS32(int *bins,
+                           int numBins,
+                           int x)
+{
+    int min;
+    int max;
+    int mid;
+
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectS32", 4,
+            "---- Calling p_psVectorBinDisectS32(%f)\n", x);
+
+    if ((x < bins[0]) ||
+            (x > bins[numBins-1])) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "p_psVectorBinDisectS32(): ordinate %f is outside vector range (%f - %f).",
+                 x, bins[0], bins[numBins-1]);
+        return(-1);
+    }
+
+    min = 0;
+    max = numBins-2;
+    mid = ((max+1)-min)/2;
+
+    while (min != max) {
+        psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectS32", 4,
+                "(min, mid, max) is (%d, %d, %d): (x, bins) is (%f, %f)\n",
+                min, mid, max, x, bins[mid]);
+
+        if (x == bins[mid]) {
+            psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectS32", 4,
+                    "---- Exiting p_psVectorBinDisectS32(): bin %d\n", min);
+            return(min);
+        } else if (x < bins[mid]) {
+            max = mid-1;
+        } else {
+            min = mid;
+        }
+        mid = ((max+1)+min)/2;
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectS32", 4,
+            "---- Exiting p_psVectorBinDisectS32(): bin %d\n", min);
+    return(min);
+}
+
+/*****************************************************************************
+p_psVectorBinDisect(): A wrapper to the above p_psVectorBinDisect().
+ *****************************************************************************/
+int p_psVectorBinDisect(psVector *bins,
+                        psScalar *x)
+{
+    if (x->type.type != bins->type.type) {
+        psError(__func__, "x->type.type != bins->type.type");
+        return(-2);
+    }
+
+    if (x->type.type == PS_TYPE_S32) {
+        return(p_psVectorBinDisectS32(bins->data.S32, bins->n, x->data.S32));
+    } else if (x->type.type == PS_TYPE_F32) {
+        return(p_psVectorBinDisectF32(bins->data.F32, bins->n, x->data.F32));
+    } else {
+        psError(__func__, "Unallowable data type.");
+        return(-2);
+    }
+    return(-1);
+}
+
+/*****************************************************************************
+p_psInterpolate1D(): This routine will take as input n-element floating
+point arrays domain and range, and the x value, assumed to lie with the
+domain vector.  It produces as output the (n-1)-order LaGrange interpolated
+value of x.
+ 
+XXX: do we error check for non-distinct domain values?
+ *****************************************************************************/
+float p_ps1DFullInterpolateF32(float *domain,
+                               float *range,
+                               int n,
+                               float x)
+{
+    int i;
+    int m;
+    static psVector *p = NULL;
+    p = psVectorRecycle(p, n, PS_TYPE_F32);
+    p_psMemSetPersistent(p, true);
+    p_psMemSetPersistent(p->data.F32, true);
+    /*
+        psVector *p = psVectorAlloc(n, PS_TYPE_F32);
+        float tmp;
+    */
+
+    psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 4,
+            "---- p_ps1DFullInterpolateF32() begin (%d-order at x=%f) (%d data points)----\n", n-1, x, n);
+
+    for (i=0;i<n;i++) {
+        psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 6,
+                "domain/range is (%f %f)\n", domain[i], range[i]);
+    }
+
+    for (i=0;i<n;i++) {
+        p->data.F32[i] = range[i];
+        psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 6,
+                "p->data.F32[%d] is %f\n", i, p->data.F32[i]);
+
+    }
+
+    // From NR, during each iteration of the m loop, we are computing the
+    // p_{i ... i+m} terms.
+    for (m=1;m<n;m++) {
+        for (i=0;i<n-m;i++) {
+            // From NR: we are computing P_{i ... i+m}
+            p->data.F32[i] = (((x-domain[i+m]) * p->data.F32[i]) +
+                              ((domain[i]-x) * p->data.F32[i+1])) /
+                             (domain[i] - domain[i+m]);
+            //printf("((%f-%f * %f) + (%f-%f * %f)) / (%f - %f)\n", x, domain[i+m], p->data.F32[i], domain[i], x, p->data.F32[i+1], domain[i], domain[i+m]);
+            psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 6,
+                    "p->data.F32[%d] is %f\n", i, p->data.F32[i]);
+        }
+    }
+    psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 4,
+            "---- p_ps1DFullInterpolateF32() end ----\n");
+
+    /*
+        tmp = p->data.F32[0];
+        psFree(p);
+        return(tmp);
+    */
+    return(p->data.F32[0]);
+}
+
+
+/*****************************************************************************
+p_ps1DInterpolateF32(): this is the base 1-D flat memory routine to perform
+LaGrange interpolation.
+ *****************************************************************************/
+float p_ps1DInterpolateF32(float *domain,
+                           float *range,
+                           int n,
+                           int order,
+                           float x)
+{
+    int binNum;
+    int numIntPoints = order+1;
+    int origin;
+
+    psTrace(".psLib.dataManip.psFunctions.p_ps1DInterpolateF32", 4,
+            "---- p_ps1DInterpolateF32() begin ----\n");
+
+    binNum = p_psVectorBinDisectF32(domain, n, x);
+
+    if (0 == numIntPoints%2) {
+        origin = binNum - ((numIntPoints/2) - 1);
+    } else {
+        origin = binNum - (numIntPoints/2);
+        if ((x-domain[binNum]) > (domain[binNum+1]-x)) {
+            // x is closer to binNum+1.
+            origin = 1 + (binNum - (numIntPoints/2));
+        }
+    }
+    if (origin < 0) {
+        origin = 0;
+    }
+    if ((origin + numIntPoints) > n) {
+        origin = n - numIntPoints;
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.p_ps1DInterpolateF32", 4,
+            "---- p_ps1DInterpolateF32() end ----\n");
+    return(p_ps1DFullInterpolateF32(&domain[origin], &range[origin], order+1, x));
+}
+
+/*****************************************************************************
+p_psVectorInterpolate(): This routine will take as input psVectors domain and
+range, and the x value, assumed to lie with the domain vector.  It produces
+as output the LaGrange interpolated value of a polynomial of the specified
+order around the point x.
+ 
+XXX: This stuff does not currently work with a mask.
+ 
+XXX: nobody asked for us to generate this routine.
+ 
+XXX: add another psScalar argument for the result.
+ 
+XXX: The VectorCopy routines seg fault when I declare range32 as static.
+ *****************************************************************************/
+psScalar *p_psVectorInterpolate(psVector *domain,
+                                psVector *range,
+                                int order,
+                                psScalar *x)
+{
+    psVector *range32 = NULL;
+    psVector *domain32 = NULL;
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+            "---- p_psVectorInterpolate() begin ----\n");
+
+    if ((domain->type.type != range->type.type) ||
+            (domain->type.type != x->type.type)) {
+        // XXX psError
+        printf("p_psVectorInterpolate(): domain->type.type != range->type.type != x->type.type\n");
+        printf("%d %d %d\n", domain->type.type, range->type.type, x->type.type);
+        exit(1);
+    }
+    if (domain->n != range->n) {
+        // XXX psError
+        printf("domain->n != range->n\n");
+        exit(1);
+    }
+    if (order > (domain->n - 1)) {
+        // XXX psError: not enough data points for order-order interpolation.
+        printf("not enough data points for order-order interpolation.\n");
+        exit(1);
+    }
+
+    if (x->type.type == PS_TYPE_F32) {
+        psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+                "---- p_psVectorInterpolate() end ----\n");
+        return(psScalarAlloc(p_ps1DInterpolateF32(domain->data.F32,
+                             range->data.F32,
+                             domain->n,
+                             order,
+                             x->data.F32), PS_TYPE_F32));
+    } else if (x->type.type == PS_TYPE_F64) {
+        // XXX: use recycled vectors here.
+        range32 = psVectorCopy(range32, range, PS_TYPE_F32);
+        domain32 = psVectorCopy(domain32, domain, PS_TYPE_F32);
+
+        psScalar *tmpScalar = psScalarAlloc((double)
+                                            p_ps1DInterpolateF32(domain32->data.F32,
+                                                                 range32->data.F32,
+                                                                 domain32->n,
+                                                                 order,
+                                                                 (float) x->data.F64), PS_TYPE_F64);
+        psFree(range32);
+        psFree(domain32);
+
+        psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+                "---- p_psVectorInterpolate() end ----\n");
+        // XXX: Convert data type to F64?
+        return(tmpScalar);
+
+    } else {
+        // XXX psError: type not supported
+        printf("XXX psError: type not supported\n");
+    }
+
+    printf("return(NULL)\n");
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+            "---- p_psVectorInterpolate() end ----\n");
+    return(NULL);
+}
+
+
+/*****************************************************************************
+psSpline1DEval(): this routine takes an existing spline of arbitrary order
+and an independent x value.  Each determines which spline that x corresponds
+to by doing a bracket disection on the domains of the spline data structure
+(p_psVectorBinDisectF32()).  Then it evaluates the spline at that x location
+by a call to the 1D polynomial functions.
+ 
+XXX: The spline eval functions require input and output to be F32.  however
+     the spline fit functions require F32 and F64.
+ *****************************************************************************/
+float psSpline1DEval(const psSpline1D *spline,
+                     float x)
+{
+    int binNum;
+    int n;
+
+    n = spline->n;
+    binNum = p_psVectorBinDisectF32(spline->domains, (spline->n)+1, x);
+    if (binNum < 0) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "psSpline1DEval(): x ordinate (%f) is outside the spline range (%f - %f).",
+                 x, (spline->domains)[0],
+                 (spline->domains)[n-1]);
+
+        if (x < (spline->domains)[0]) {
+            return(psPolynomial1DEval(x, spline->spline[0]));
+        } else if (x > (spline->domains)[n-1]) {
+            return(psPolynomial1DEval(x, spline->spline[n-1]));
+        }
+    }
+
+    return(psPolynomial1DEval(x, spline->spline[binNum]));
+}
+
+// XXX: The spline eval functions require input and output to be F32.
+// however the spline fit functions require F32 and F64.
+psVector *psSpline1DEvalVector(const psVector *x,
+                               const psSpline1D *spline)
+{
+    int i;
+    psVector *tmpVector;
+
+    tmpVector = psVectorAlloc(x->n, PS_TYPE_F32);
+    if (x->type.type == PS_TYPE_F32) {
+        for (i=0;i<x->n;i++) {
+            tmpVector->data.F32[i] = psSpline1DEval(spline, x->data.F32[i]);
+        }
+    } else if (x->type.type == PS_TYPE_F64) {
+        for (i=0;i<x->n;i++) {
+            tmpVector->data.F32[i] = psSpline1DEval(spline, (float) x->data.F64[i]);
+        }
+    } else {
+        psError(__func__, "Unknown data type.\n");
+        return(NULL);
+    }
+
+    return(tmpVector);
+}
Index: /branches/rel3/psLib/src/dataManip/psFunctions.h
===================================================================
--- /branches/rel3/psLib/src/dataManip/psFunctions.h	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/psFunctions.h	(revision 2163)
@@ -0,0 +1,435 @@
+/** @file psFunctions.h
+*  \brief Standard Mathematical Functions.
+*  \ingroup Stats
+*
+*  This file will hold the prototypes for procedures which allocate, free,
+*  and evaluate various polynomials.  Those polynomial structures are also
+*  defined here.
+*
+*  @ingroup Stats
+*
+*  @author Someone at IfA
+*  @author George Gusciora, MHPCC
+*
+*  @version $Revision: 1.30 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-06 00:48:15 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#if !defined(PS_FUNCTIONS_H)
+#define PS_FUNCTIONS_H
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <float.h>
+#include <math.h>
+
+#include "psVector.h"
+#include "psScalar.h"
+
+/** \addtogroup Stats
+ *  \{
+ */
+
+/** Evaluate a non-normalized Gaussian with the given mean and sigma at the
+ *  given coordianate.  
+ *
+ *  Note that this is not a Gaussian deviate.  The evaluated Gaussian is: 
+ *        \f[ exp(-\frac{(x-mean)^2}{2\sigma^2}) \f] 
+ *
+ *  @return float      value on the gaussian curve given the input parameters
+ */
+float psGaussian(
+    float x,                           ///< Value at which to evaluate
+    float mean,                        ///< Mean for the Gaussian
+    float stddev,                      ///< Standard deviation for the Gaussian
+    bool normal                        ///< Indicates whether result should be normalized
+);
+
+/** Produce a vector of random numbers from a Gaussian distribution with
+ *  the specified mean and sigma 
+ *  
+ *  @return psVector*    vector of random numbers
+ *  
+ */
+psVector* psGaussianDev(
+    float mean,                        ///< The mean of the Gaussian
+    float sigma,                       ///< The sigma of the Gaussian
+    int Npts                           ///< The size of the vector
+);
+
+typedef enum {
+    PS_POLYNOMIAL_ORD,                 ///< Ordinary Polynomial
+    PS_POLYNOMIAL_CHEB                 ///< Chebyshev Polynomial
+} psPolynomialType;
+
+/** One-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int n;                             ///< Number of terms
+    float *coeff;                      ///< Coefficients
+    float *coeffErr;                   ///< Error in coefficients
+    char *mask;                        ///< Coefficient mask
+}
+psPolynomial1D;
+
+/** Two-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    float **coeff;                     ///< Coefficients
+    float **coeffErr;                  ///< Error in coefficients
+    char **mask;                       ///< Coefficients mask
+}
+psPolynomial2D;
+
+/** Three-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    int nZ;                            ///< Number of terms in z
+    float ***coeff;                    ///< Coefficients
+    float ***coeffErr;                 ///< Error in coefficients
+    char ***mask;                      ///< Coefficients mask
+}
+psPolynomial3D;
+
+/** Four-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nW;                            ///< Number of terms in w
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    int nZ;                            ///< Number of terms in z
+    float ****coeff;                   ///< Coefficients
+    float ****coeffErr;                ///< Error in coefficients
+    char ****mask;                     ///< Coefficients mask
+}
+psPolynomial4D;
+
+
+/** Allocates a psPolynomial1D structure with n terms
+ *
+ *  @return  psPolynomial1D*    new 1-D polynomial struct
+ */
+psPolynomial1D* psPolynomial1DAlloc(
+    int n,                              ///< Number of terms
+    psPolynomialType type               ///< Polynomial Type
+);
+
+/** Allocates a 2-D polynomial structure
+ *
+ *  @return  psPolynomial2D*    new 2-D polynomial struct
+ */
+psPolynomial2D* psPolynomial2DAlloc(
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Allocates a 3-D polynomial structure
+ *
+ *  @return  psPolynomial3D*    new 3-D polynomial struct
+ */
+psPolynomial3D* psPolynomial3DAlloc(
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    int nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Allocates a 4-D polynomial structure
+ *
+ *  @return  psPolynomial4D*    new 4-D polynomial struct
+ */
+psPolynomial4D* psPolynomial4DAlloc(
+    int nW,                            ///< Number of terms in w
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    int nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Evaluates a 1-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+float psPolynomial1DEval(
+    float x,                           ///< location at which to evaluate
+    const psPolynomial1D* myPoly       ///< Coefficients for the polynomial
+);
+
+/** Evaluates a 2-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+float psPolynomial2DEval(
+    float x,                           ///< x location at which to evaluate
+    float y,                           ///< y location at which to evaluate
+    const psPolynomial2D* myPoly       ///< Coefficients for the polynomial
+);
+
+/** Evaluates a 3-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+float psPolynomial3DEval(
+    float x,                           ///< x location at which to evaluate
+    float y,                           ///< y location at which to evaluate
+    float z,                           ///< z location at which to evaluate
+    const psPolynomial3D* myPoly       ///< Coefficients for the polynomial
+);
+
+/** Evaluates a 4-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+float psPolynomial4DEval(
+    float w,                           ///< w location at which to evaluate
+    float x,                           ///< x location at which to evaluate
+    float y,                           ///< y location at which to evaluate
+    float z,                           ///< z location at which to evaluate
+    const psPolynomial4D* myPoly       ///< Coefficients for the polynomial
+);
+
+psVector *psPolynomial1DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                   const psPolynomial1D *myPoly   ///< Coefficients for the polynomial
+                                  );
+
+psVector *psPolynomial2DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                   const psVector *y,             ///< y locations at which to evaluate
+                                   const psPolynomial2D *myPoly   ///< Coefficients for the polynomial
+                                  );
+
+psVector *psPolynomial3DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                   const psVector *y,             ///< y locations at which to evaluate
+                                   const psVector *z,             ///< z locations at which to evaluate
+                                   const psPolynomial3D *myPoly   ///< Coefficients for the polynomial
+                                  );
+
+psVector *psPolynomial4DEvalVector(const psVector *w,             ///< w locations at which to evaluate
+                                   const psVector *x,             ///< x locations at which to evaluate
+                                   const psVector *y,             ///< y locations at which to evaluate
+                                   const psVector *z,             ///< z locations at which to evaluate
+                                   const psPolynomial4D *myPoly   ///< Coefficients for the polynomial
+                                  );
+
+/*****************************************************************************/
+
+/* Double-precision polynomials, mainly for use in astrometry */
+
+/** Double-precision one-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int n;                             ///< Number of terms
+    double *coeff;                     ///< Coefficients
+    double *coeffErr;                  ///< Error in coefficients
+    char *mask;                        ///< Coefficient mask
+}
+psDPolynomial1D;
+
+/** Double-precision two-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    double **coeff;                    ///< Coefficients
+    double **coeffErr;                 ///< Error in coefficients
+    char **mask;                       ///< Coefficients mask
+}
+psDPolynomial2D;
+
+/** Double-precision three-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    int nZ;                            ///< Number of terms in z
+    double ***coeff;                   ///< Coefficients
+    double ***coeffErr;                ///< Error in coefficients
+    char ***mask;                      ///< Coefficient mask
+}
+psDPolynomial3D;
+
+/** Double-precision four-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nW;                            ///< Number of terms in w
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    int nZ;                            ///< Number of terms in z
+    double ****coeff;                  ///< Coefficients
+    double ****coeffErr;               ///< Error in coefficients
+    char ****mask;                     ///< Coefficients mask
+}
+psDPolynomial4D;
+
+/** Allocates a double-precision 1-D polynomial structure with n terms
+ *
+ *  @return  psPolynomial1D*    new double-precision 1-D polynomial struct
+ */
+psDPolynomial1D* psDPolynomial1DAlloc(
+    int n,                             ///< Number of terms
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Allocates a double-precision 2-D polynomial structure
+ *
+ *  @return  psPolynomial2D*    new double-precision 2-D polynomial struct
+ */
+psDPolynomial2D* psDPolynomial2DAlloc(
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Allocates a double-precision 3-D polynomial structure
+ *
+ *  @return  psPolynomial3D*    new double-precision 3-D polynomial struct
+ */
+psDPolynomial3D* psDPolynomial3DAlloc(
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    int nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Allocates a double-precision 4-D polynomial structure
+ *
+ *  @return  psPolynomial4D*    new double-precision 4-D polynomial struct
+ */
+psDPolynomial4D* psDPolynomial4DAlloc(
+    int nW,                            ///< Number of terms in w
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    int nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Evaluates a double-precision 1-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+double psDPolynomial1DEval(
+    double x,                          ///< Value at which to evaluate
+    const psDPolynomial1D* myPoly      ///< Coefficients for the polynomial
+);
+
+/** Evaluates a double-precision 2-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+double psDPolynomial2DEval(
+    double x,                           ///< Value x at which to evaluate
+    double y,                           ///< Value y at which to evaluate
+    const psDPolynomial2D* myPoly       ///< Coefficients for the polynomial
+);
+
+/** Evaluates a double-precision 3-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+double psDPolynomial3DEval(
+    double x,                          ///< Value x at which to evaluate
+    double y,                          ///< Value y at which to evaluate
+    double z,                          ///< Value z at which to evaluate
+    const psDPolynomial3D* myPoly      ///< Coefficients for the polynomial
+);
+
+/** Evaluates a double-precision 4-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+double psDPolynomial4DEval(
+    double w,                          ///< Value w at which to evaluate
+    double x,                          ///< Value x at which to evaluate
+    double y,                          ///< Value y at which to evaluate
+    double z,                          ///< Value z at which to evaluate
+    const psDPolynomial4D* myPoly      ///< Coefficients for the polynomial
+);
+
+psVector *psDPolynomial1DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                    const psDPolynomial1D *myPoly  ///< Coefficients for the polynomial
+                                   );
+
+psVector *psDPolynomial2DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                    const psVector *y,             ///< y locations at which to evaluate
+                                    const psDPolynomial2D *myPoly  ///< Coefficients for the polynomial
+                                   );
+
+psVector *psDPolynomial3DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                    const psVector *y,             ///< y locations at which to evaluate
+                                    const psVector *z,             ///< z locations at which to evaluate
+                                    const psDPolynomial3D *myPoly  ///< Coefficients for the polynomial
+                                   );
+
+psVector *psDPolynomial4DEvalVector(const psVector *w,             ///< w locations at which to evaluate
+                                    const psVector *x,             ///< x locations at which to evaluate
+                                    const psVector *y,             ///< y locations at which to evaluate
+                                    const psVector *z,             ///< z locations at which to evaluate
+                                    const psDPolynomial4D *myPoly  ///< Coefficients for the polynomial
+                                   );
+
+
+
+typedef struct
+{
+    int n;                        ///< The number of spline polynomials
+    psPolynomial1D **spline;      ///< An array of n pointers to the spline polynomials
+    float *p_psDeriv2;            ///< For cubic splines, the second derivative at each domain point.  Size is n+1.
+    float *domains;               ///< The boundaries between each spline piece.  Size is n+1.
+}
+psSpline1D;
+
+psSpline1D *psSpline1DAlloc(int n,
+                            int order,
+                            float min,
+                            float max);
+
+int p_psSpline1DFree(psSpline1D *tmpSpline);
+
+psSpline1D *psSpline1DAllocGeneric(const psVector *bounds,
+                                   int order);
+
+float psSpline1DEval(const psSpline1D *spline,
+                     float x);
+
+psVector *psSpline1DEvalVector(const psVector *x,
+                               const psSpline1D *spline);
+
+int p_psVectorBinDisectF32(float *bins,
+                           int numBins,
+                           float x);
+
+int p_psVectorBinDisectS32(int *bins,
+                           int numBins,
+                           int x);
+
+int p_psVectorBinDisect(psVector *bins,
+                        psScalar *x);
+
+psScalar *p_psVectorInterpolate(psVector *domain,
+                                psVector *range,
+                                int order,
+                                psScalar *x);
+
+float p_psNRSpline1DEval(psSpline1D *spline,
+                         const psVector* restrict x,
+                         const psVector* restrict y,
+                         float X);
+
+/* \} */// End of MathGroup Functions
+
+#endif
+
Index: /branches/rel3/psLib/src/dataManip/psMatrix.c
===================================================================
--- /branches/rel3/psLib/src/dataManip/psMatrix.c	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/psMatrix.c	(revision 2163)
@@ -0,0 +1,539 @@
+/** @file  psMatrix.c
+ *
+ *  @brief Provides functions for linear algebra operations on psImages and psVectors. 
+ *
+ *  Functions are provided to:
+ *      Transpose a psImage
+ *      Compute LUD
+ *      Solve LUD
+ *      Matrix inversion
+ *      Calculate determinant
+ *      Matrix addition
+ *      Matrix subtraction
+ *      Matrix multiplication
+ *      Calculate Eigenvectors
+ *      Convert matrix to vector
+ *      Convert vector to matrix
+ *
+ *  These functions treat psImages as if they were matrices, therefore there is no psMatrix.
+ *
+ *  @author Ross Harman, MHPCC
+ *   
+ *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-08 02:48:01 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include <string.h>
+#include <gsl/gsl_matrix.h>
+#include <gsl/gsl_linalg.h>
+#include <gsl/gsl_permutation.h>
+#include <gsl/gsl_eigen.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psImage.h"
+#include "psVector.h"
+#include "psMatrix.h"
+
+/** Preprocessor macro to generate error a NULL image */
+#define PS_CHECK_NULL_VECTOR(NAME, RETURN)                                                          \
+if (NAME == NULL || NAME->data.V == NULL) {                                                         \
+    psError(__func__,"Invalid operation: %s or its data is NULL.", #NAME);                          \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to create vector based on another */
+#define PS_CHECK_ALLOC_VECTOR(NAME, SIZE, PS_TYPE)                                                  \
+if(NAME == NULL) {                                                                                  \
+    NAME = psVectorAlloc(SIZE, PS_TYPE);                                                            \
+}
+
+/** Preprocessor macro to generate error for zero length vector */
+#define PS_CHECK_SIZE_VECTOR(NAME, RETURN)                                                          \
+if (NAME->n < 1) {                                                                                  \
+    psError(__func__,"Invalid operation: %s has zero n value.", #NAME);                             \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to generate error a NULL image */
+#define PS_CHECK_NULL_IMAGE(NAME, RETURN)                                                           \
+if (NAME == NULL || NAME->data.V == NULL) {                                                         \
+    psError(__func__,"Invalid operation: %s or its data is NULL.", #NAME);                          \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to create image based on another */
+#define PS_CHECK_ALLOC_IMAGE(NAME, NCOLS, NROWS, PS_TYPE)                                           \
+if(NAME == NULL) {                                                                                  \
+    NAME = psImageAlloc(NCOLS, NROWS, PS_TYPE);                                                     \
+}
+
+/** Preprocessor macro to generate error for zero length rows or columns */
+#define PS_CHECK_SIZE_IMAGE(NAME, RETURN)                                                           \
+if (NAME->numCols < 1 || NAME->numRows < 1) {                                                       \
+    psError(__func__,"Invalid operation: %s has zero rows or columns (%dx%d).", #NAME,              \
+            NAME->numCols, NAME->numRows);                                                          \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to generate error for image dimensionality not set to PS_DIMEN_IMAGE */
+#define PS_CHECK_DIMEN_AND_TYPE(NAME, PS_DIMEN, RETURN)                                             \
+if (NAME->type.dimen != PS_DIMEN) {                                                                 \
+    psError(__func__,"Invalid operation: %s incorrect dimensionality %d.", #NAME, PS_DIMEN);        \
+    return RETURN;                                                                                  \
+} else if(NAME->type.type != PS_TYPE_F64) {                                                         \
+    psError(__func__, "Invalid operation: %s not PS_TYPE_F64.", #NAME);                             \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to check that input is not equal to output */
+#define PS_CHECK_POINTERS(NAME1, NAME2, RETURN)                                                     \
+if (NAME1 == NAME2) {                                                                               \
+    psError(__func__,"Invalid operation: Pointer to %s is same as %s.", #NAME1, #NAME2);            \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to check that an image is square */
+#define PS_CHECK_SQUARE(NAME, RETURN)                                                               \
+if (NAME->numCols != NAME->numRows) {                                                               \
+    psError(__func__,"Invalid operation: %s not square array.", #NAME);                             \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to initalize a GSL matrix. */
+#define PS_GSL_MATRIX_INITIALIZE(LHS_NAME, RHS_NAME)                                                \
+LHS_NAME.size1 = numRows;                                                                           \
+LHS_NAME.size2 = numCols;                                                                           \
+LHS_NAME.tda   = numCols;                                                                           \
+LHS_NAME.data  = RHS_NAME;
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+psImage* psMatrixLUD(psImage* outImage, psVector* outPerm, psImage* inImage)
+{
+    int signum = 0;
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix lu;
+    gsl_permutation perm;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_NULL_IMAGE(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+    PS_CHECK_ALLOC_VECTOR(outPerm, inImage->numRows, inImage->type.type);
+    PS_CHECK_NULL_VECTOR(outPerm, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(outPerm, PS_DIMEN_VECTOR, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type) * numRows * numCols;
+
+    // Initialize GSL data
+    perm.size = numCols;
+    outPerm->n = numCols;
+    perm.data = outPerm->data.V;
+    PS_GSL_MATRIX_INITIALIZE(lu, outImage->data.V[0]);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Copy psImage input data into GSL matrix data to keep input data pristine
+    memcpy(lu.data, inImage->data.V[0], arraySize);
+
+    // Calculate LU decomposition
+    gsl_linalg_LU_decomp(&lu, &perm, &signum);
+
+    return outImage;
+}
+
+psVector* psMatrixLUSolve(psVector* outVector, const psImage* inImage,
+                          const psVector* inVector, const psVector* inPerm)
+{
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix lu;
+    gsl_permutation perm;
+    gsl_vector b;
+    gsl_vector x;
+
+    // Error checks
+    PS_CHECK_POINTERS(outVector, inVector, outVector);
+    PS_CHECK_POINTERS(inVector, inPerm, outVector);
+    PS_CHECK_POINTERS(outVector, inPerm, outVector);
+    PS_CHECK_NULL_IMAGE(inImage, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outVector);
+    PS_CHECK_SIZE_IMAGE(inImage, outVector);
+    PS_CHECK_ALLOC_VECTOR(outVector, inImage->numRows, inImage->type.type);
+    PS_CHECK_NULL_VECTOR(outVector, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_VECTOR, outVector);
+    PS_CHECK_NULL_VECTOR(inVector, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_VECTOR, outVector);
+    PS_CHECK_NULL_VECTOR(inPerm, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inPerm, PS_DIMEN_VECTOR, outVector);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type) * numRows * numCols;
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(lu, inImage->data.V[0]);
+
+    outVector->n = numCols;
+
+    perm.size = inPerm->n;
+    perm.data = inPerm->data.V;
+
+    b.size = inVector->n;
+    b.stride = 1;
+    b.data = inVector->data.V;
+
+    x.size = numCols;
+    x.stride = 1;
+    x.data = outVector->data.V;
+
+    // Solve for {x} in equation: {b} = [A]{x}
+    gsl_linalg_LU_solve(&lu, &perm, &b, &x);
+
+    return outVector;
+}
+
+psImage* psMatrixInvert(psImage* outImage, const psImage* inImage, float *restrict det)
+{
+    int signum = 0;
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix inv;
+    gsl_matrix *lu;
+    gsl_permutation *perm = NULL;
+
+    // Error checks
+    if (det == NULL) {
+        psError(__func__, "Invalid operation: determinant argument is NULL.");
+        return outImage;
+    }
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_NULL_IMAGE(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type) * numRows * numCols;
+
+    // Allocate GSL structs
+    perm = gsl_permutation_alloc(inImage->numRows);
+    lu = gsl_matrix_alloc(numRows, numCols);
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(inv, outImage->data.V[0]);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Copy psImage input data into GSL matrix data to keep input data pristine
+    memcpy(lu->data, inImage->data.V[0], arraySize);
+
+    // Invert data and calculate determinant
+    gsl_linalg_LU_decomp(lu, perm, &signum);
+    gsl_linalg_LU_invert(lu, perm, &inv);
+    *det = (float)gsl_linalg_LU_det(lu, signum);
+
+    // Free GSL structs
+    gsl_permutation_free(perm);
+    gsl_matrix_free(lu);
+
+    return outImage;
+}
+
+float *psMatrixDeterminant(const psImage* restrict inImage)
+{
+    int signum = 0;
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    float *det = NULL;
+    gsl_matrix *lu = NULL;
+    gsl_permutation *perm = NULL;
+
+    // Error checks
+    PS_CHECK_NULL_IMAGE(inImage, NULL);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, NULL);
+    PS_CHECK_SIZE_IMAGE(inImage, NULL);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type) * numRows * numCols;
+
+    // Allocate GSL structs
+    perm = gsl_permutation_alloc(numRows);
+    lu = gsl_matrix_alloc(numRows, numCols);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, 0);
+
+    // Copy psImage input data into GSL matrix data to keep input data pristine
+    memcpy(lu->data, inImage->data.V[0], arraySize);
+
+    // Calculate determinant
+    det = (float *)psAlloc(sizeof(float));
+    gsl_linalg_LU_decomp(lu, perm, &signum);
+    *det = (float)gsl_linalg_LU_det(lu, signum);
+
+    // Free GSL structs
+    gsl_permutation_free(perm);
+    gsl_matrix_free(lu);
+
+    return det;
+}
+
+psImage* psMatrixMultiply(psImage* outImage, psImage* inImage1, psImage* inImage2)
+{
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix m1;
+    gsl_matrix m2;
+    gsl_matrix m3;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage1, outImage, outImage);
+    PS_CHECK_POINTERS(inImage1, inImage2, outImage);
+    PS_CHECK_NULL_IMAGE(inImage1, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage1, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage1, outImage);
+    PS_CHECK_NULL_IMAGE(inImage2, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage2, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage2, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage2->numCols, inImage2->numRows, inImage2->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(inImage1, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage1->numRows;
+    numCols = inImage1->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(outImage->type.type) * numRows * numCols;
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(m1, inImage1->data.V[0]);
+    PS_GSL_MATRIX_INITIALIZE(m2, inImage2->data.V[0]);
+    PS_GSL_MATRIX_INITIALIZE(m3, outImage->data.V[0]);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage1, outImage);
+    PS_CHECK_SQUARE(inImage2, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    gsl_linalg_matmult(&m1, &m2, &m3);
+
+    return outImage;
+}
+
+psImage* psMatrixTranspose(psImage* outImage, const psImage* inImage)
+{
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix trans;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_NULL_IMAGE(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type) * numRows * numCols;
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(trans, outImage->data.V[0]);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Copy psImage input data into psImage output data to keep input data pristine
+    memcpy(outImage->data.V[0], inImage->data.V[0], arraySize);
+
+    // Transpose data
+    gsl_matrix_transpose(&trans);
+
+    return outImage;
+}
+
+psImage* psMatrixEigenvectors(psImage* outImage, psImage* inImage)
+{
+    int numRows = 0;
+    int numCols = 0;
+    gsl_vector *eVals = NULL;
+    gsl_eigen_symmv_workspace *w = NULL;
+    gsl_matrix out;
+    gsl_matrix in;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_NULL_IMAGE(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(in, inImage->data.V[0]);
+    PS_GSL_MATRIX_INITIALIZE(out, outImage->data.V[0]);
+
+    // Allocate GSL structs
+    eVals = gsl_vector_alloc(numRows);
+    w = gsl_eigen_symmv_alloc(numRows);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Calculate Eigenvalues and Eigenvectors...Eigenvalues not currently used
+    gsl_eigen_symmv(&in, eVals, &out, w);
+
+    // Free GSL structs
+    gsl_eigen_symmv_free(w);
+    gsl_vector_free(eVals);
+
+    return outImage;
+}
+
+psVector* psMatrixToVector(psVector* outVector, const psImage* inImage)
+{
+    int size = 0;
+
+    // Error checks
+    PS_CHECK_NULL_IMAGE(inImage, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outVector);
+    PS_CHECK_SIZE_IMAGE(inImage, outVector);
+
+    if (inImage->numRows == 1) {
+        // Create transposed row vector
+        PS_CHECK_ALLOC_VECTOR(outVector, inImage->numCols, inImage->type.type);
+        outVector->type.dimen = PS_DIMEN_TRANSV;
+    } else if (inImage->numCols == 1) {
+        // Create non-transposed column vector
+        PS_CHECK_ALLOC_VECTOR(outVector, inImage->numRows, inImage->type.type);
+    } else {
+        psError(__func__, "Image does not have dim with 1 col or 1 row: (%d x %d).", inImage->numRows,
+                inImage->numCols);
+        return outVector;
+    }
+
+    PS_CHECK_NULL_VECTOR(outVector, outVector);
+
+    // More checks
+    if (outVector->type.dimen == PS_DIMEN_VECTOR) {
+        PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_VECTOR, outVector);
+
+        if (outVector->n == 0) {
+            outVector->n = inImage->numRows;
+        }
+
+        if (outVector->n != inImage->numRows) {
+            psError(__func__, "Image and vector sizes differ: (%d vs %d).", inImage->numRows, outVector->n);
+            return outVector;
+        }
+
+        size = PSELEMTYPE_SIZEOF(inImage->type.type) * inImage->numRows;
+
+    } else if (outVector->type.dimen == PS_DIMEN_TRANSV) {
+        PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_TRANSV, outVector);
+
+        if (outVector->n == 0) {
+            outVector->n = inImage->numCols;
+        }
+
+        if (outVector->n != inImage->numCols) {
+            psError(__func__, "Image and vector sizes differ: (%d vs %d).", inImage->numCols, outVector->n);
+            return outVector;
+        }
+
+        size = PSELEMTYPE_SIZEOF(inImage->type.type) * inImage->numCols;
+    }
+
+    memcpy(outVector->data.V, inImage->data.V[0], size);
+
+    return outVector;
+}
+
+psImage* psVectorToMatrix(psImage* outImage, const psVector* inVector)
+{
+    int size = 0;
+
+    // Error checks
+    PS_CHECK_NULL_VECTOR(inVector, outImage);
+
+    if (inVector->type.dimen == PS_DIMEN_VECTOR) {
+        PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_VECTOR, outImage);
+        PS_CHECK_SIZE_VECTOR(inVector, outImage);
+        PS_CHECK_ALLOC_IMAGE(outImage, 1, inVector->n, PS_TYPE_F64)
+        // More checks for PS_DIMEN_VECTOR
+        if (outImage->numCols > 1) {
+            psError(__func__, "Image has more than 1 column: numCols = %d.", outImage->numCols);
+            return outImage;
+        } else if (outImage->numRows != inVector->n) {
+            psError(__func__, "Image and vector sizes differ: (%d vs %d).", outImage->numRows, inVector->n);
+            return outImage;
+        }
+
+        size = PSELEMTYPE_SIZEOF(outImage->type.type) * outImage->numRows;
+
+    } else if (inVector->type.dimen == PS_DIMEN_TRANSV) {
+        PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_TRANSV, outImage);
+        PS_CHECK_SIZE_VECTOR(inVector, outImage);
+        PS_CHECK_ALLOC_IMAGE(outImage, inVector->n, 1, PS_TYPE_F64)
+        // More checks for PS_DIMEN_TRANSV
+        if (outImage->numRows > 1) {
+            psError(__func__, "Image has more than 1 row: numRows = %d.", outImage->numRows);
+            return outImage;
+        } else if (outImage->numCols != inVector->n) {
+            psError(__func__, "Image and vector sizes differ: (%d vs %d).", outImage->numCols, inVector->n);
+            return outImage;
+        }
+
+        size = PSELEMTYPE_SIZEOF(outImage->type.type) * outImage->numCols;
+    }
+
+    PS_CHECK_NULL_IMAGE(outImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+
+    memcpy(outImage->data.V[0], inVector->data.V, size);
+
+    return outImage;
+}
Index: /branches/rel3/psLib/src/dataManip/psMatrix.h
===================================================================
--- /branches/rel3/psLib/src/dataManip/psMatrix.h	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/psMatrix.h	(revision 2163)
@@ -0,0 +1,166 @@
+
+/** @file  psMatrix.h
+ *
+ *  @brief Provides functions for linear algebra operations on psImages and psVectors. 
+ *
+ *  Functions are provided to:
+ *      Transpose a psImage
+ *      Compute LUD
+ *      Solve LUD
+ *      Matrix inversion
+ *      Calculate determinant
+ *      Matrix multiplication
+ *      Calculate Eigenvectors
+ *      Convert matrix to vector
+ *      Convert vector to matrix
+ *
+ *  These functions treat psImages as if they were matrices, therefore there is no psMatrix. These functions
+ *  operate only with the psF64 data type.
+ *
+ *  @ingroup Matrix
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-21 23:44:10 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PSMATRIX_H
+#define PSMATRIX_H
+
+/// @addtogroup Matrix
+/// @{
+
+/** LU Decomposition of psImage matrix.
+ *
+ *  Performs a LU decomposition on a psImage matrix and returns the LU matrix. If the user specifies NULL for
+ *  the outImage or outPerm arguments, then they will be automatically created. The input image must 
+ *  be square. This function operates only with the psF64 data type. Input and output arguments should not be 
+ *  the same. GSL indexes the top row as the zero row, not the bottom.  
+ *
+ *  @return  psImage* : Pointer to LU decomposed psImage.
+ */
+psImage* psMatrixLUD(
+    psImage* outImage,                 ///< Image to return, or NULL.
+    psVector* outPerm,                 ///< Output permutation vector used by psMatrixLUSolve.
+    psImage* inImage                   ///< Image to decompose.
+);
+
+/** LU Solution of psImage matrix.
+ *
+ *  Solves for and returns the psVector, {x} in the equation [A]{x} = {b}. If the user specifies NULL as the 
+ *  outVector argument, then it will automatically be created. The input image must be square. This function 
+ *  operates only with the psF64 data type. Input and output arguments should not be the same. GSL indexes 
+ *  the top row as the zero row, not the bottom.  
+ *
+ *  @return  psVector* : Pointer to psVector solution of matrix equation.
+ */
+psVector* psMatrixLUSolve(
+    psVector* outVector,               ///< Vector to return, or NULL.
+    const psImage* luImage,            ///< LU-decomposed matrix.
+    const psVector* inVector,          ///< Vector right-hand-side of equation.
+    const psVector* inPerm             ///< Permutation vector resulting from psMatrixLUD function.
+);
+
+/** Invert psImage matrix.
+ *
+ *  Inverts a psImage matrix and returns the determinant as an option through the argument list. If the user
+ *  specifies NULL as the outImage argument, then it will automatically be created. The input image must be 
+ *  square. This function operates only with the psF64 data type. Input and output arguments should not be 
+ *  the same. GSL indexes the top row as the zero row, not the bottom.  
+ *
+ *  @return  psImage* : Pointer to inverted psImage.
+ */
+psImage* psMatrixInvert(
+    psImage* outImage,                 ///< Image to return, or NULL for in-place substitution.
+    const psImage* inImage,            ///< Image to be inverted
+    float *restrict det                ///< Determinant to return, or NULL
+);
+
+/** Calculate psImage matrix determinant.
+ *
+ *  Calculates the determinant of a psImage matrix and returns the single precision floating point result. The
+ *  input image must be square. This function operates only with the psF64 data type. GSL indexes the top row 
+ *  as the zero row, not the bottom.  
+ *
+ *  @return  float: Determinant from psImage.
+ */
+float *psMatrixDeterminant(
+    const psImage* restrict inMatrix   ///< Image used to calculate determinant.
+);
+
+/** Performs psImage matrix multiplication.
+ *
+ *  Performs a classical matrix multiplication involving row and column operations. Input images must be square 
+ *  and the same size. If the user specifies NULL as the outImage argument, then it will automatically be 
+ *  created. This function operates only with the psF64 data type. GSL indexes the top row as the
+ *  zero row, not the bottom.  
+ *
+ *  @return  psImage* : Pointer to resulting psImage.
+ */
+psImage* psMatrixMultiply(
+    psImage* outImage,                 ///< Matrix to return, or NULL.
+    psImage* inImage1,                 ///< First input image.
+    psImage* inImage2                  ///< Second input image.
+);
+
+/** Transpose matrix.
+ *
+ *  Performs psImage matrix transpose by substituting existing rows for columns. The input image must be 
+ *  square. If the user specifies NULL as the outImage argument, then it will automaticallty be created.
+ *  This function operates only with the psF64 data type. GSL indexes the top row as the zero 
+ *  row, not the bottom.  
+ *
+ *  @return  psImage* : Pointer to transposed psImage.
+ */
+psImage* psMatrixTranspose(
+    psImage* outImage,                 ///< Image to return, or NULL
+    const psImage* inImage             ///< Image to transpose
+);
+
+/** Calculate matrix eigenvectors.
+ *
+ *  Calculates the eigenvectors for a matrix. The input image must be symmetric and square. If the user 
+ *  specifies NULL as the outImage argument, then it will automatically be created. This function operates 
+ *  only with the psF64 data type. GSL indexes the top row as the zero row, not the bottom.  
+ *
+ *  @return  psImage* : Pointer to matrix of Eigenvectors.
+ */
+psImage* psMatrixEigenvectors(
+    psImage* outImage,                 ///< Eigenvectors to return, or NULL.
+    psImage* inImage                   ///< Input image.
+);
+
+/** Convert matrix to vector.
+ *
+ *  Converts a 1-d psImage matrix into a vector. If the user specifies NULL as the outVector argument, then it
+ *  will automatically be created based on the input image (PS_DIMEN_VECTOR for an input image with 1 col or
+ *  PS_DIMENT_TRANSV for an input image with 1 row). Either the number of rows or the number of colums of the
+ *  input matrix must be 1. This function operates only  with the psF64 data type.
+ *
+ *  @return  psVector* : Pointer to psVector.
+ */
+psVector* psMatrixToVector(
+    psVector* outVector,               ///< Vector to return, or NULL.
+    const psImage* inImage             ///< Image to convert.
+);
+
+/** Convert vector to matrix.
+ *
+ *  Converts a vector into a psImage matrix. If the dimensionality of the vector is PS_DIMEN_VECTOR, then the
+ *  resulting psImage is a 1d column. If the dimensionality of the vector is PS_DIMEN_TRANSV, then the
+ *  resulting psImage is a 1d row. If the user specifies NULL as the outImage argument,  then it will 
+ *  automatically be created. This function operates only with the psF64 data type.  
+ *
+ *  @return  psVector* : Pointer to psIamge.
+ */
+psImage* psVectorToMatrix(
+    psImage* outImage,                 ///< Matrix to return, or NULL.
+    const psVector* inVector           ///< Vector to convert.
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/dataManip/psMatrixVectorArithmetic.c
===================================================================
--- /branches/rel3/psLib/src/dataManip/psMatrixVectorArithmetic.c	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/psMatrixVectorArithmetic.c	(revision 2163)
@@ -0,0 +1,911 @@
+/** @file  psMatrixVectorArithmetic.c
+ *
+ *  @brief Provides unary and binary functions for simple matrix and vector element operations. Functions
+ *  include:
+ *
+ *      Addition (+)
+ *      Subtraction (-)
+ *      Multiplication (*)
+ *      Division (/)
+ *      Power (^)
+ *      Minimum (min)
+ *      Maximum (max)
+ *      Absolute value (abs)
+ *      Exponent (exp)
+ *      Natural Log (ln)
+ *      Power of 10 (ten)
+ *      Log (log)
+ *      Sine (sin or dsin)
+ *      Cosine (cos or dcos)
+ *      Tangent (tan or dtan)
+ *      Arcsine (asin or dasin)
+ *      Arccosine (acos or dacos)
+ *      Arctan (atan or datan)
+ *
+ *  Currently only vector-vector and image-image binary operations are supported.
+ *
+ *  @ingroup MatrixVectorArithmetic
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.28 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-08 02:48:01 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************
+ *  INCLUDE FILES                                                             *
+ ******************************************************************************/
+#include <string.h>
+#include <math.h>
+#include <stdint.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psImage.h"
+#include "psVector.h"
+#include "psScalar.h"
+#include "psLogMsg.h"
+
+/*****************************************************************************
+ *  FUNCTION IMPLEMENTATION - LOCAL                                          *
+ *****************************************************************************/
+
+// Conversion for degrees to radians
+#define D2R 0.01745329252111111  /* PI/180 */
+
+// Conversion for radians to degrees
+#define R2D 57.29577950924861   /* 180.0/PI */
+
+/* IEEE Standards on floating-point makes this function pointless, really.
+// Division with NAN checking
+static complex double psNanDiv(complex double a, complex double b)
+{
+    complex double out = 0 + 0i;
+ 
+    out = a / b;
+    if (isnan(creal(out)) || isnan(cimag(out))) {
+        psError(__func__, ": Divide by zero");
+    }
+ 
+    return out;
+}
+*/
+
+// Binary SCALAR_XXXX operations
+#define SCALAR_SCALAR(OUT,IN1,OP,IN2,TYPE)                                                                   \
+{                                                                                                            \
+    ps##TYPE *o = NULL;                                                                                      \
+    ps##TYPE *i1 = NULL;                                                                                     \
+    ps##TYPE *i2 = NULL;                                                                                     \
+    o  = &((psScalar* )OUT)->data.TYPE;                                                                      \
+    i1 = &((psScalar* )IN1)->data.TYPE;                                                                      \
+    i2 = &((psScalar* )IN2)->data.TYPE;                                                                      \
+    *o = OP;                                                                                                 \
+}
+
+#define SCALAR_VECTOR(OUT,IN1,OP,IN2,TYPE)                                                                   \
+{                                                                                                            \
+    int i = 0;                                                                                               \
+    int npt = 0;                                                                                             \
+    ps##TYPE *o = NULL;                                                                                      \
+    ps##TYPE *i1 = NULL;                                                                                     \
+    ps##TYPE *i2 = NULL;                                                                                     \
+    npt  = ((psVector* )IN1)->n;                                                                             \
+    o  = ((psVector* )OUT)->data.TYPE;                                                                       \
+    i1 = &((psScalar* )IN1)->data.TYPE;                                                                      \
+    i2 = ((psVector* )IN2)->data.TYPE;                                                                       \
+    for (i=0; i < npt; i++, o++, i2++) {                                                                     \
+        *o = OP;                                                                                             \
+    }                                                                                                        \
+}
+
+#define SCALAR_IMAGE(OUT,IN1,OP,IN2,TYPE)                                                                    \
+{                                                                                                            \
+    int i = 0;                                                                                               \
+    int j = 0;                                                                                               \
+    int numRows = 0;                                                                                         \
+    int numCols = 0;                                                                                         \
+    ps##TYPE *o = NULL;                                                                                      \
+    ps##TYPE *i1 = NULL;                                                                                     \
+    ps##TYPE *i2 = NULL;                                                                                     \
+    numRows = ((psImage* )IN1)->numRows;                                                                     \
+    numCols = ((psImage* )IN1)->numCols;                                                                     \
+    for(j = 0; j < numCols; j++) {                                                                           \
+        o  = ((psImage* )OUT)->data.TYPE[j];                                                                 \
+        i1 = &((psScalar* )IN1)->data.TYPE;                                                                  \
+        i2 = ((psImage* )IN2)->data.TYPE[j];                                                                 \
+        for(i = 0; i < numRows; i++, o++, i2++) {                                                            \
+            *o = OP;                                                                                         \
+        }                                                                                                    \
+    }                                                                                                        \
+}
+
+// Binary VECTOR_XXXX operations
+#define VECTOR_SCALAR(OUT,IN1,OP,IN2,TYPE)                                                                   \
+{                                                                                                            \
+    int i = 0;                                                                                               \
+    int n1 = 0;                                                                                              \
+    ps##TYPE *o = NULL;                                                                                      \
+    ps##TYPE *i1 = NULL;                                                                                     \
+    ps##TYPE *i2 = NULL;                                                                                     \
+    n1  = ((psVector* )IN1)->n;                                                                              \
+    o  = ((psVector* )OUT)->data.TYPE;                                                                       \
+    i1 = ((psVector* )IN1)->data.TYPE;                                                                       \
+    i2 = &((psScalar* )IN2)->data.TYPE;                                                                      \
+    for (i=0; i < n1; i++, o++, i1++) {                                                                      \
+        *o = OP;                                                                                             \
+    }                                                                                                        \
+}
+
+#define VECTOR_VECTOR(OUT,IN1,OP,IN2,TYPE)                                                                   \
+{                                                                                                            \
+    int i = 0;                                                                                               \
+    int n1 = 0;                                                                                              \
+    int n2 = 0;                                                                                              \
+    ps##TYPE *o = NULL;                                                                                      \
+    ps##TYPE *i1 = NULL;                                                                                     \
+    ps##TYPE *i2 = NULL;                                                                                     \
+    n1  = ((psVector* )IN1)->n;                                                                              \
+    n2  = ((psVector* )IN2)->n;                                                                              \
+    if(n1 != n2) {                                                                                           \
+        psError(__func__, ": Inconsistent element count: %d vs %d", n1, n2);                                 \
+        if (OUT != IN1 && OUT != IN2) {                                                                      \
+            psFree(OUT);                                                                                     \
+        }                                                                                                    \
+        return NULL;                                                                                         \
+    }                                                                                                        \
+    o  = ((psVector* )OUT)->data.TYPE;                                                                       \
+    i1 = ((psVector* )IN1)->data.TYPE;                                                                       \
+    i2 = ((psVector* )IN2)->data.TYPE;                                                                       \
+    for (i=0; i < n1; i++, o++, i1++, i2++) {                                                                \
+        *o = OP;                                                                                             \
+    }                                                                                                        \
+}
+
+#define VECTOR_IMAGE(OUT,IN1,OP,IN2,TYPE)                                                                    \
+{                                                                                                            \
+    int i = 0;                                                                                               \
+    int j = 0;                                                                                               \
+    int n1 = 0;                                                                                              \
+    int numRows2 = 0;                                                                                        \
+    int numCols2 = 0;                                                                                        \
+    psDimen dim1 = 0;                                                                                        \
+    ps##TYPE *o = NULL;                                                                                      \
+    ps##TYPE *i1 = NULL;                                                                                     \
+    ps##TYPE *i2 = NULL;                                                                                     \
+    n1  = ((psVector* )IN1)->n;                                                                              \
+    dim1 = ((psVector* )IN1)->type.dimen;                                                                    \
+    numRows2 = ((psImage* )IN2)->numRows;                                                                    \
+    numCols2 = ((psImage* )IN2)->numCols;                                                                    \
+    \
+    if(dim1 == PS_DIMEN_VECTOR) { /* Regular vectors */                                                      \
+        if(n1!=numRows2) {                                                                                   \
+            psError(__func__, ": Inconsistent element count: %d vs %d", n1, numRows2);                       \
+            if (OUT != IN1 && OUT != IN2) {                                                                  \
+                psFree(OUT);                                                                                 \
+            }                                                                                                \
+            return NULL;                                                                                     \
+        }                                                                                                    \
+        \
+        i1 = ((psVector* )IN1)->data.TYPE;                                                                   \
+        for(j = 0; j < numRows2; j++, i1++) {                                                                \
+            o  = ((psImage* )OUT)->data.TYPE[j];                                                             \
+            i2 = ((psImage* )IN2)->data.TYPE[j];                                                             \
+            for(i = 0; i < numCols2; i++, o++, i2++) {                                                       \
+                *o = OP;                                                                                     \
+            }                                                                                                \
+        }                                                                                                    \
+    } else {  /* Transposed vectors */                                                                       \
+        if(n1!=numCols2) {                                                                                   \
+            psError(__func__, ": Inconsistent element count: %d vs %d", n1, numCols2);                       \
+            if (OUT != IN1 && OUT != IN2) {                                                                  \
+                psFree(OUT);                                                                                 \
+            }                                                                                                \
+            return NULL;                                                                                     \
+        }                                                                                                    \
+        \
+        for(j = 0; j < numRows2; j++) {                                                                      \
+            o  = ((psImage* )OUT)->data.TYPE[j];                                                             \
+            i1 = ((psVector* )IN1)->data.TYPE;                                                               \
+            i2 = ((psImage* )IN2)->data.TYPE[j];                                                             \
+            for(i = 0; i < numCols2; i++, o++, i1++, i2++) {                                                 \
+                *o = OP;                                                                                     \
+            }                                                                                                \
+        }                                                                                                    \
+    }                                                                                                        \
+}
+
+// Binary IMAGE_XXXX operations
+#define IMAGE_SCALAR(OUT,IN1,OP,IN2,TYPE)                                                                    \
+{                                                                                                            \
+    int i = 0;                                                                                               \
+    int j = 0;                                                                                               \
+    int numRows = 0;                                                                                         \
+    int numCols = 0;                                                                                         \
+    ps##TYPE *o = NULL;                                                                                      \
+    ps##TYPE *i1 = NULL;                                                                                     \
+    ps##TYPE *i2 = NULL;                                                                                     \
+    numRows = ((psImage* )IN1)->numRows;                                                                     \
+    numCols = ((psImage* )IN1)->numCols;                                                                     \
+    for(j = 0; j < numRows; j++) {                                                                           \
+        o  = ((psImage* )OUT)->data.TYPE[j];                                                                 \
+        i1 = ((psImage* )IN1)->data.TYPE[j];                                                                 \
+        i2 = &((psScalar* )IN2)->data.TYPE;                                                                  \
+        for(i = 0; i < numCols; i++, o++, i1++) {                                                            \
+            *o = OP;                                                                                         \
+        }                                                                                                    \
+    }                                                                                                        \
+}
+
+#define IMAGE_VECTOR(OUT,IN1,OP,IN2,TYPE)                                                                    \
+{                                                                                                            \
+    int i = 0;                                                                                               \
+    int j = 0;                                                                                               \
+    int n2 = 0;                                                                                              \
+    int numRows1 = 0;                                                                                        \
+    int numCols1 = 0;                                                                                        \
+    psDimen dim2 = 0;                                                                                        \
+    ps##TYPE *o = NULL;                                                                                      \
+    ps##TYPE *i1 = NULL;                                                                                     \
+    ps##TYPE *i2 = NULL;                                                                                     \
+    n2  = ((psVector* )IN2)->n;                                                                              \
+    dim2 = ((psVector* )IN2)->type.dimen;                                                                    \
+    numRows1 = ((psImage* )IN1)->numRows;                                                                    \
+    numCols1 = ((psImage* )IN1)->numCols;                                                                    \
+    \
+    if(dim2 == PS_DIMEN_VECTOR) { /* Regular vectors */                                                      \
+        if(n2!=numRows1) {                                                                                   \
+            psError(__func__, ": Inconsistent element count: %d vs %d", n2, numRows1);                       \
+            if (OUT != IN1 && OUT != IN2) {                                                                  \
+                psFree(OUT);                                                                                 \
+            }                                                                                                \
+            return NULL;                                                                                     \
+        }                                                                                                    \
+        \
+        i2 = ((psVector* )IN2)->data.TYPE;                                                                   \
+        for(j = 0; j < numRows1; j++, i1++) {                                                                \
+            o  = ((psImage* )OUT)->data.TYPE[j];                                                             \
+            i1 = ((psImage* )IN1)->data.TYPE[j];                                                             \
+            for(i = 0; i < numCols1; i++, o++, i1++) {                                                       \
+                *o = OP;                                                                                     \
+            }                                                                                                \
+        }                                                                                                    \
+    } else {  /* Transposed vectors */                                                                       \
+        if(n2!=numCols1) {                                                                                   \
+            psError(__func__, ": Inconsistent element count: %d vs %d", n2, numCols1);                       \
+            if (OUT != IN1) {                                                                                \
+                psFree(OUT);                                                                                 \
+            }                                                                                                \
+            return NULL;                                                                                     \
+        }                                                                                                    \
+        \
+        for(j = 0; j < numRows1; j++) {                                                                      \
+            o  = ((psImage* )OUT)->data.TYPE[j];                                                             \
+            i1 = ((psVector* )IN2)->data.TYPE;                                                               \
+            i2 = ((psImage* )IN1)->data.TYPE[j];                                                             \
+            for(i = 0; i < numCols1; i++, o++, i2++, i1++) {                                                 \
+                *o = OP;                                                                                     \
+            }                                                                                                \
+        }                                                                                                    \
+    }                                                                                                        \
+}
+
+#define IMAGE_IMAGE(OUT,IN1,OP,IN2,TYPE)                                                                     \
+{                                                                                                            \
+    int i = 0;                                                                                               \
+    int j = 0;                                                                                               \
+    int numRows1 = 0;                                                                                        \
+    int numCols1 = 0;                                                                                        \
+    int numRows2 = 0;                                                                                        \
+    int numCols2 = 0;                                                                                        \
+    ps##TYPE *o = NULL;                                                                                      \
+    ps##TYPE *i1 = NULL;                                                                                     \
+    ps##TYPE *i2 = NULL;                                                                                     \
+    numRows1 = ((psImage* )IN1)->numRows;                                                                    \
+    numCols1 = ((psImage* )IN1)->numCols;                                                                    \
+    numRows2 = ((psImage* )IN2)->numRows;                                                                    \
+    numCols2 = ((psImage* )IN2)->numCols;                                                                    \
+    if(numRows1!=numRows2 || numCols1!=numCols2) {                                                           \
+        psError(__func__, ": Inconsistent element count: numRows: %d vs %d numCols: %d vs %d", numRows1,     \
+                numRows2, numCols1, numCols2);                                                               \
+        if (OUT != IN1 && OUT != IN2) {                                                                      \
+            psFree(OUT);                                                                                     \
+        }                                                                                                    \
+        return NULL;                                                                                         \
+    }                                                                                                        \
+    for(j = 0; j < numRows1; j++) {                                                                          \
+        o  = ((psImage* )OUT)->data.TYPE[j];                                                                 \
+        i1 = ((psImage* )IN1)->data.TYPE[j];                                                                 \
+        i2 = ((psImage* )IN2)->data.TYPE[j];                                                                 \
+        for(i = 0; i < numCols1; i++, o++, i1++, i2++) {                                                     \
+            *o = OP;                                                                                         \
+        }                                                                                                    \
+    }                                                                                                        \
+}
+
+// Preprocessor macro function to create arithmetic function based on input type
+#define BINARY_TYPE(DIM1,DIM2,OUT,IN1,OP,IN2)                                                                \
+switch (IN1->type) {                                                                                         \
+case PS_TYPE_U8:                                                                                             \
+    DIM1##_##DIM2(OUT,IN1,OP,IN2,U8);                                                                        \
+    break;                                                                                                   \
+case PS_TYPE_U16:                                                                                            \
+    DIM1##_##DIM2(OUT,IN1,OP,IN2,U16);                                                                       \
+    break;                                                                                                   \
+case PS_TYPE_U32:                                                                                            \
+    DIM1##_##DIM2(OUT,IN1,OP,IN2,U32);                                                                       \
+    break;                                                                                                   \
+case PS_TYPE_U64:                                                                                            \
+    DIM1##_##DIM2(OUT,IN1,OP,IN2,U64);                                                                       \
+    break;                                                                                                   \
+case PS_TYPE_S8:                                                                                             \
+    DIM1##_##DIM2(OUT,IN1,OP,IN2,S8);                                                                        \
+    break;                                                                                                   \
+case PS_TYPE_S16:                                                                                            \
+    DIM1##_##DIM2(OUT,IN1,OP,IN2,S16);                                                                       \
+    break;                                                                                                   \
+case PS_TYPE_S32:                                                                                            \
+    DIM1##_##DIM2(OUT,IN1,OP,IN2,S32);                                                                       \
+    break;                                                                                                   \
+case PS_TYPE_S64:                                                                                            \
+    DIM1##_##DIM2(OUT,IN1,OP,IN2,S64);                                                                       \
+    break;                                                                                                   \
+case PS_TYPE_F32:                                                                                            \
+    DIM1##_##DIM2(OUT,IN1,OP,IN2,F32);                                                                       \
+    break;                                                                                                   \
+case PS_TYPE_F64:                                                                                            \
+    DIM1##_##DIM2(OUT,IN1,OP,IN2,F64);                                                                       \
+    break;                                                                                                   \
+case PS_TYPE_C32:                                                                                            \
+    DIM1##_##DIM2(OUT,IN1,OP,IN2,C32);                                                                       \
+    break;                                                                                                   \
+case PS_TYPE_C64:                                                                                            \
+    DIM1##_##DIM2(OUT,IN1,OP,IN2,C64);                                                                       \
+    break;                                                                                                   \
+default:                                                                                                     \
+    psError(__func__, ": Invalid PS_TYPE: %d", IN1->type);                                                   \
+    if (OUT != IN1 && OUT != IN2) {                                                                          \
+        psFree(OUT);                                                                                         \
+    }                                                                                                        \
+    return NULL;                                                                                             \
+}
+
+// Preprocessor macro function to create arithmetic function operation name
+#define BINARY_OP(DIM1,DIM2,OUT,IN1,OP,IN2)                                                                  \
+if(!strncmp(OP, "+", 1)) {                                                                                   \
+    BINARY_TYPE(DIM1,DIM2,OUT,IN1,*i1 + *i2,IN2);                                                            \
+} else if(!strncmp(OP, "-", 1)) {                                                                            \
+    BINARY_TYPE(DIM1,DIM2,OUT,IN1,*i1 - *i2,IN2);                                                            \
+} else if(!strncmp(OP, "*", 1)) {                                                                            \
+    BINARY_TYPE(DIM1,DIM2,OUT,IN1,*i1 * *i2,IN2);                                                            \
+} else if(!strncmp(OP, "/", 1)) {                                                                            \
+    BINARY_TYPE(DIM1,DIM2,OUT,IN1,*i1 / *i2,IN2);                                                    \
+} else if(!strncmp(OP, "^", 1)) {                                                                            \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN1->type)) {                                                                \
+        BINARY_TYPE(DIM1,DIM2,OUT,IN1,cpow(*i1,*i2),IN2);                                                    \
+    } else {                                                                                                 \
+        BINARY_TYPE(DIM1,DIM2,OUT,IN1,pow(*i1,*i2),IN2);                                                     \
+    }                                                                                                        \
+} else if(!strncmp(OP, "min", 3)) {                                                                          \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN1->type)) {                                                                \
+        psError(__func__, ": Minimum operation not supported for complex numbers");                          \
+        if (OUT != IN1 && OUT != IN2) {                                                                      \
+            psFree(OUT);                                                                                     \
+        }                                                                                                    \
+        return NULL;                                                                                         \
+    } else {                                                                                                 \
+        BINARY_TYPE(DIM1,DIM2,OUT,IN1,fmin(*i1,*i2),IN2);                                                    \
+    }                                                                                                        \
+} else if(!strncmp(OP, "max", 3)) {                                                                          \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN1->type)) {                                                                \
+        psError(__func__, ": Maximum operation not supported for complex numbers");                          \
+        if (OUT != IN1 && OUT != IN2) {                                                                      \
+            psFree(OUT);                                                                                     \
+        }                                                                                                    \
+        return NULL;                                                                                         \
+    } else {                                                                                                 \
+        BINARY_TYPE(DIM1,DIM2,OUT,IN1,fmax(*i1,*i2),IN2);                                                    \
+    }                                                                                                        \
+} else {                                                                                                     \
+    psError(__func__, ": Invalid operation: %s", OP);                                                        \
+    if (OUT != IN1 && OUT != IN2) {                                                                          \
+        psFree(OUT);                                                                                         \
+    }                                                                                                        \
+    return NULL;                                                                                             \
+}
+
+void *psBinaryOp(void *out, void *in1, char *op, void *in2)
+{
+    psDimen dim1 = 0;
+    psDimen dim2 = 0;
+    psElemType elType1 = 0;
+    psElemType elType2 = 0;
+    psType* psType1 = NULL;
+    psType* psType2 = NULL;
+
+    psType1 = (psType* ) in1;
+    if (psType1 == NULL) {
+        psError(__func__, ": Line %d - Null in1 argument", __LINE__);
+        if (out != in1 && out != in2) {
+            psFree(out);
+        }
+        return NULL;
+    }
+
+    psType2 = (psType* ) in2;
+    if (psType2 == NULL) {
+        psError(__func__, ": Line %d - Null in2 argument", __LINE__);
+        if (out != in1 && out != in2) {
+            psFree(out);
+        }
+        return NULL;
+    }
+
+    if (op == NULL) {
+        psError(__func__, ": Line %d - Null op argument", __LINE__);
+        if (out != in1 && out != in2) {
+            psFree(out);
+        }
+        return NULL;
+    }
+
+    dim1 = psType1->dimen;
+    dim2 = psType2->dimen;
+    elType1 = psType1->type;
+    elType2 = psType2->type;
+
+    if (elType1 != elType2) {
+        psError(__func__, ": Line %d - Element types for arguments inconsistent: (%d, %d)", __LINE__,
+                elType1, elType2);
+        if (out != in1 && out != in2) {
+            psFree(out);
+        }
+        return NULL;
+    }
+
+    if (dim1 == PS_DIMEN_OTHER || dim2 == PS_DIMEN_OTHER) {
+        psError(__func__, ": Line %d - PS_DIMEN_OTHER not allowed for arguments: (%d, %d)", __LINE__,
+                dim1, dim2);
+        if (out != in1 && out != in2) {
+            psFree(out);
+        }
+        return NULL;
+    }
+
+    if (dim1 == PS_DIMEN_VECTOR || dim1 == PS_DIMEN_TRANSV) {
+        if (((psVector* ) in1)->n == 0) {
+            psLogMsg(__func__, PS_LOG_WARN, ": Line %d - Vector contains zero elements");
+        }
+    } else if (dim1 == PS_DIMEN_IMAGE) {
+        if (((psImage* ) in1)->numCols == 0 || ((psImage* ) in1)->numRows == 0) {
+            psLogMsg(__func__, PS_LOG_WARN, ": Line %d - Image contains zero length row or cols");
+        }
+    }
+
+    if (dim2 == PS_DIMEN_VECTOR || dim2 == PS_DIMEN_TRANSV) {
+        if (((psVector* ) in2)->n == 0) {
+            psLogMsg(__func__, PS_LOG_WARN, ": Line %d - Vector contains zero elements");
+        }
+    } else if (dim2 == PS_DIMEN_IMAGE) {
+        if (((psImage* ) in2)->numCols == 0 || ((psImage* ) in2)->numRows == 0) {
+            psLogMsg(__func__, PS_LOG_WARN, ": Line %d - Image contains zero length row or cols");
+        }
+    }
+
+    if (dim1 == PS_DIMEN_SCALAR) {
+        if ( out != NULL && ((psType*)out)->dimen != dim2) {
+            if (out != in1 && out != in2) {
+                psFree(out);
+            }
+            out = NULL;
+        }
+        if (dim2 == PS_DIMEN_SCALAR) {
+            if (out == NULL || ((psScalar*)out)->type.type != elType1) {
+                if (out != in1 && out != in2) {
+                    psFree(out);
+                }
+                out = psScalarAlloc(0.0,elType1);
+            }
+            BINARY_OP(SCALAR, SCALAR, out, psType1, op, psType2);       // scalar op scalar
+        } else if (dim2 == PS_DIMEN_VECTOR || dim2 == PS_DIMEN_TRANSV) {
+            out = psVectorRecycle(out,((psVector*)in2)->n,elType1);
+            if (out == NULL) {
+                psError(__func__, "Couldn't create a proper output psVector.");
+                return NULL;
+            }
+            BINARY_OP(SCALAR, VECTOR, out, psType1, op, psType2);       // scalar op vector
+        } else if (dim2 == PS_DIMEN_IMAGE) {
+            out = psImageRecycle(out, ((psImage* ) in2)->numCols, ((psImage* ) in2)->numRows,elType1);
+            if (out == NULL) {
+                psError(__func__, "Couldn't create a proper output psImage.");
+                return NULL;
+            }
+            BINARY_OP(SCALAR, IMAGE, out, psType1, op, psType2);        // scalar op image
+        } else {
+            psError(__func__, ": Line %d - Invalid dimensionality for in2 arg: %d", __LINE__, dim2);
+        }
+    } else if (dim1 == PS_DIMEN_VECTOR || dim1 == PS_DIMEN_TRANSV) {
+        if (dim2 == PS_DIMEN_SCALAR) {
+            out = psVectorRecycle(out,((psVector*)in1)->n,elType1);
+            if (out == NULL) {
+                psError(__func__, "Couldn't create a proper output psVector.");
+                return NULL;
+            }
+            BINARY_OP(VECTOR, SCALAR, out, psType1, op, psType2);       // vector op scalar
+        } else if (dim2 == PS_DIMEN_VECTOR || dim2 == PS_DIMEN_TRANSV) {
+            out = psVectorRecycle(out,((psVector*)in2)->n,elType2);
+            if (out == NULL) {
+                psError(__func__, "Couldn't create a proper output psVector.");
+                return NULL;
+            }
+            BINARY_OP(VECTOR, VECTOR, out, psType1, op, psType2);       // vector op vector
+        } else if (dim2 == PS_DIMEN_IMAGE) {
+            out = psImageRecycle(out, ((psImage* ) in2)->numCols, ((psImage* ) in2)->numRows, elType2);
+            if (out == NULL) {
+                psError(__func__, "Couldn't create a proper output psImage.");
+                return NULL;
+            }
+            BINARY_OP(VECTOR, IMAGE, out, psType1, op, psType2);        // vector op image
+        } else {
+            psError(__func__, ": Line %d - Invalid dimensionality for in2 arg: %d", __LINE__, dim2);
+        }
+    } else if (dim1 == PS_DIMEN_IMAGE) {
+        out = psImageRecycle(out, ((psImage*)in1)->numCols, ((psImage*)in1)->numRows, elType1);
+        if (out == NULL) {
+            psError(__func__, "Couldn't create a proper output psImage.");
+            return NULL;
+        }
+        if (dim2 == PS_DIMEN_SCALAR) {
+            BINARY_OP(IMAGE, SCALAR, out, psType1, op, psType2);        // image op scalar
+        } else if (dim2 == PS_DIMEN_VECTOR || dim2 == PS_DIMEN_TRANSV) {
+            BINARY_OP(IMAGE, VECTOR, out, psType1, op, psType2);        // image op vector
+        } else if (dim2 == PS_DIMEN_IMAGE) {
+            BINARY_OP(IMAGE, IMAGE, out, psType1, op, psType2); // image op image
+        } else {
+            if (out != in1 && out != in2) {
+                psFree(out);
+            }
+            psError(__func__, ": Line %d - Invalid dimensionality for in2 arg: %d", __LINE__, dim2);
+            return NULL;
+        }
+    } else {
+        if (out != in1 && out != in2) {
+            psFree(out);
+        }
+        psError(__func__, ": Line %d - Invalid dimensionality for in1 arg: %d", __LINE__, dim1);
+        return NULL;
+    }
+
+    // Automtically free psScalar types, since they are usually allocated in the argument list when this
+    // function is called, provided that the input is not the output.
+    if(psType1->dimen==PS_DIMEN_SCALAR && in1!=out) {
+        psFree(in1);
+    }
+
+    if(psType2->dimen==PS_DIMEN_SCALAR && in2!=out) {
+        psFree(in2);
+    }
+
+    return out;
+}
+
+// Unary SCALAR operations
+#define SCALAR(OUT,IN,OP,TYPE)                                                                               \
+{                                                                                                            \
+    ps##TYPE *o = NULL;                                                                                      \
+    ps##TYPE *i1 = NULL;                                                                                     \
+    o  = &((psScalar* )OUT)->data.TYPE;                                                                      \
+    i1 = &((psScalar* )IN)->data.TYPE;                                                                       \
+    *o = OP;                                                                                                 \
+}
+
+// Unary IMAGE operations
+#define VECTOR(OUT,IN,OP,TYPE)                                                                               \
+{                                                                                                            \
+    int i = 0;                                                                                               \
+    int nIn = 0;                                                                                             \
+    int nOut = 0;                                                                                            \
+    ps##TYPE *o = NULL;                                                                                      \
+    ps##TYPE *i1 = NULL;                                                                                     \
+    nIn = ((psVector* )IN)->n;                                                                               \
+    nOut = ((psVector* )OUT)->n;                                                                             \
+    if(nIn != nOut) {                                                                                        \
+        psError(__func__, ": Inconsistent element count: %d vs %d", nIn, nOut);                              \
+        if (OUT != IN) {                                                                                     \
+            psFree(OUT);                                                                                     \
+        }                                                                                                    \
+        return NULL;                                                                                         \
+    }                                                                                                        \
+    o  = ((psVector* )OUT)->data.TYPE;                                                                       \
+    i1 = ((psVector* )IN)->data.TYPE;                                                                        \
+    for(i = 0; i < nIn; i++, o++, i1++) {                                                                    \
+        *o = OP;                                                                                             \
+    }                                                                                                        \
+}
+
+// Unary IMAGE operations
+#define IMAGE(OUT,IN,OP,TYPE)                                                                                \
+{                                                                                                            \
+    int i = 0;                                                                                               \
+    int j = 0;                                                                                               \
+    int numRowsIn = 0;                                                                                       \
+    int numColsIn = 0;                                                                                       \
+    int numRowsOut = 0;                                                                                      \
+    int numColsOut = 0;                                                                                      \
+    ps##TYPE *o = NULL;                                                                                      \
+    ps##TYPE *i1 = NULL;                                                                                     \
+    numRowsIn = ((psImage* )IN)->numRows;                                                                    \
+    numColsIn = ((psImage* )IN)->numCols;                                                                    \
+    numRowsOut = ((psImage* )OUT)->numRows;                                                                  \
+    numColsOut = ((psImage* )OUT)->numCols;                                                                  \
+    if(numRowsIn!=numRowsOut || numColsIn!=numColsOut) {                                                     \
+        psError(__func__, ": Inconsistent element count: numRows: %d vs %d numCols: %d vs %d", numRowsIn,    \
+                numRowsOut, numColsIn, numColsOut);                                                          \
+        if (OUT != IN) {                                                                                     \
+            psFree(OUT);                                                                                     \
+        }                                                                                                    \
+        return NULL;                                                                                         \
+    }                                                                                                        \
+    for(j = 0; j < numRowsIn; j++) {                                                                         \
+        o  = ((psImage* )OUT)->data.TYPE[j];                                                                 \
+        i1 = ((psImage* )IN)->data.TYPE[j];                                                                  \
+        for(i = 0; i < numColsIn; i++, o++, i1++) {                                                          \
+            *o = OP;                                                                                         \
+        }                                                                                                    \
+    }                                                                                                        \
+}
+
+// Preprocessor macro function to create arithmetic function based on input type
+#define UNARY_TYPE(DIM,OUT,IN,OP)                                                                            \
+switch (IN->type) {                                                                                          \
+case PS_TYPE_S32:                                                                                            \
+    DIM(OUT,IN,OP,S32);                                                                                      \
+    break;                                                                                                   \
+case PS_TYPE_F32:                                                                                            \
+    DIM(OUT,IN,OP,F32);                                                                                      \
+    break;                                                                                                   \
+case PS_TYPE_F64:                                                                                            \
+    DIM(OUT,IN,OP,F64);                                                                                      \
+    break;                                                                                                   \
+case PS_TYPE_C32:                                                                                            \
+    DIM(OUT,IN,OP,C32);                                                                                      \
+    break;                                                                                                   \
+case PS_TYPE_S8:                                                                                             \
+    DIM(OUT,IN,OP,C32);                                                                                      \
+    break;                                                                                                   \
+case PS_TYPE_U8:                                                                                             \
+    DIM(OUT,IN,OP,C32);                                                                                      \
+    break;                                                                                                   \
+case PS_TYPE_S16:                                                                                            \
+    DIM(OUT,IN,OP,C32);                                                                                      \
+    break;                                                                                                   \
+case PS_TYPE_U16:                                                                                            \
+    DIM(OUT,IN,OP,C32);                                                                                      \
+    break;                                                                                                   \
+case PS_TYPE_U32:                                                                                            \
+    DIM(OUT,IN,OP,C32);                                                                                      \
+    break;                                                                                                   \
+case PS_TYPE_S64:                                                                                            \
+    DIM(OUT,IN,OP,C32);                                                                                      \
+    break;                                                                                                   \
+case PS_TYPE_U64:                                                                                            \
+    DIM(OUT,IN,OP,C32);                                                                                      \
+    break;                                                                                                   \
+case PS_TYPE_C64:                                                                                            \
+    DIM(OUT,IN,OP,C32);                                                                                      \
+    break;                                                                                                   \
+default:                                                                                                     \
+    psError(__func__, ": Invalid PS_TYPE: %d", IN->type);                                                    \
+    if (OUT != IN) {                                                                                         \
+        psFree(OUT);                                                                                         \
+    }                                                                                                        \
+    return NULL;                                                                                             \
+}
+
+// Preprocessor macro function to create arithmetic function operation name. Functions below that add
+// FLT_EPSILON are done so to align results with a 64 bit computing architecture
+#define UNARY_OP(DIM,OUT,IN,OP)                                                                              \
+if(!strncmp(OP, "abs", 3)) {                                                                                 \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,cabs(*i1));                                                                    \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,fabs(*i1));                                                                    \
+    }                                                                                                        \
+} else if(!strncmp(OP, "exp", 3)) {                                                                          \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,cexp(*i1));                                                                    \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,exp(*i1));                                                                     \
+    }                                                                                                        \
+} else if(!strncmp(OP, "ln", 2)) {                                                                           \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,clog(*i1));                                                                    \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,log(*i1));                                                                     \
+    }                                                                                                        \
+} else if(!strncmp(OP, "ten", 3)) {                                                                          \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,cpow(10.0,*i1));                                                               \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,pow(10.0,*i1));                                                                \
+    }                                                                                                        \
+} else if(!strncmp(OP, "log", 3)) {                                                                          \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,clog(*i1)/log(10.0));                                                          \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,log10(*i1));                                                                   \
+    }                                                                                                        \
+} else if(!strncmp(OP, "sin", 3)) {                                                                          \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,csin(*i1));                                                                    \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,sin(*i1));                                                                     \
+    }                                                                                                        \
+} else if(!strncmp(OP, "dsin", 4)) {                                                                         \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,csin(*i1*D2R));                                                                \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,sin(*i1*D2R));                                                                 \
+    }                                                                                                        \
+} else if(!strncmp(OP, "cos", 3)) {                                                                          \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,ccos(*i1));                                                                    \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,cos(*i1));                                                                     \
+    }                                                                                                        \
+} else if(!strncmp(OP, "dcos", 4)) {                                                                         \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,ccos(*i1*D2R));                                                                \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,cos(*i1*D2R));                                                                 \
+    }                                                                                                        \
+} else if(!strncmp(OP, "tan", 3)) {                                                                          \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,ctan(*i1));                                                                    \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,tan(*i1));                                                                     \
+    }                                                                                                        \
+} else if(!strncmp(OP, "dtan", 4)) {                                                                         \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,ctan(*i1*D2R));                                                                \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,tan(*i1*D2R));                                                                 \
+    }                                                                                                        \
+} else if(!strncmp(OP, "asin", 4)) {                                                                         \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,casin(*i1));                                                                   \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,asin(*i1));                                                                    \
+    }                                                                                                        \
+} else if(!strncmp(OP, "dasin", 5)) {                                                                        \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,R2D*casin(*i1));                                                               \
+    } else if(PS_IS_PSELEMTYPE_INT(IN->type)) {                                                              \
+        UNARY_TYPE(DIM,OUT,IN,(R2D*asin(*i1)));                                                              \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,(R2D*asin(*i1)));                                                              \
+    }                                                                                                        \
+} else if(!strncmp(OP, "acos", 4)) {                                                                         \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,cacos(*i1));                                                                   \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,acos(*i1));                                                                    \
+    }                                                                                                        \
+} else if(!strncmp(OP, "dacos", 5)) {                                                                        \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,R2D*cacos(*i1));                                                               \
+    } else if(PS_IS_PSELEMTYPE_INT(IN->type)) {                                                              \
+        UNARY_TYPE(DIM,OUT,IN,(R2D*acos(*i1)));                                                              \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,R2D*acos(*i1));                                                                \
+    }                                                                                                        \
+} else if(!strncmp(OP, "atan", 4)) {                                                                         \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,catan(*i1));                                                                   \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,atan(*i1));                                                                    \
+    }                                                                                                        \
+} else if(!strncmp(OP, "datan", 5)) {                                                                        \
+    if(PS_IS_PSELEMTYPE_COMPLEX(IN->type)) {                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,R2D*catan(*i1));                                                               \
+    } else {                                                                                                 \
+        UNARY_TYPE(DIM,OUT,IN,R2D*atan(*i1));                                                                \
+    }                                                                                                        \
+} else {                                                                                                     \
+    psError(__func__, ": Invalid operation: %s", OP);                                                        \
+}
+
+void *psUnaryOp(void *out, void *in, char *op)
+{
+    psDimen dimIn = 0;
+    psElemType elTypeIn = 0;
+    psType* psTypeIn = NULL;
+
+    psTypeIn = (psType* ) in;
+    if (psTypeIn == NULL) {
+        psError(__func__, ": Line %d - Null in argument", __LINE__);
+        if (out != in) {
+            psFree(out);
+        }
+        return NULL;
+    }
+
+    if (op == NULL) {
+        psError(__func__, ": Line %d - Null op argument", __LINE__);
+        if (out != in) {
+            psFree(out);
+        }
+        return NULL;
+    }
+
+    dimIn = psTypeIn->dimen;
+    elTypeIn = psTypeIn->type;
+
+    switch (dimIn) {
+    case PS_DIMEN_SCALAR:
+        if (out == NULL ||
+                ((psType*)out)->dimen != PS_DIMEN_SCALAR ||
+                ((psScalar*)out)->type.type != elTypeIn) {
+            psFree(out);
+            out = psScalarAlloc(0.0,elTypeIn);
+        }
+        UNARY_OP(SCALAR, out, psTypeIn, op);    // scalar
+        break;
+    case PS_DIMEN_VECTOR:
+    case PS_DIMEN_TRANSV:
+        if (((psVector*)in)->n == 0) {
+            if (out != in) {
+                psFree(out);
+            }
+            psError(__func__, ": Line %d - Vector contains zero elements");
+            return NULL;
+        }
+
+        out = psVectorRecycle(out,
+                              ((psVector*)in)->n,
+                              elTypeIn);
+        if (out == NULL) {
+            psError(__func__, "Couldn't create a proper output psVector.");
+            return NULL;
+        }
+
+        UNARY_OP(VECTOR, out, psTypeIn, op);    // vector
+        break;
+    case PS_DIMEN_IMAGE:
+        if (((psImage* ) in)->numCols == 0 || ((psImage* ) in)->numRows == 0) {
+            if (out != in) {
+                psFree(out);
+            }
+            psError(__func__, ": Line %d - Image contains zero length row or cols");
+            return NULL;
+        }
+
+        out = psImageRecycle(out,
+                             ((psImage*)in)->numCols,
+                             ((psImage*)in)->numRows,
+                             elTypeIn);
+        if (out == NULL) {
+            psError(__func__, "Couldn't create a proper output psImage.");
+            return NULL;
+        }
+
+        UNARY_OP(IMAGE, out, psTypeIn, op);     // image
+        break;
+    default:
+        if (out != in) {
+            psFree(out);
+        }
+        psError(__func__, ": Line %d - Invalid dimensionality for in arg: %d", __LINE__, dimIn);
+        return NULL;
+    }
+
+    // Automtically free psScalar types, since they are usually allocated in the argument list when this
+    // function is called, provided that the input is not the output.
+    if(psTypeIn->dimen==PS_DIMEN_SCALAR && in!=out) {
+        psFree(in);
+    }
+
+    return out;
+}
Index: /branches/rel3/psLib/src/dataManip/psMatrixVectorArithmetic.h
===================================================================
--- /branches/rel3/psLib/src/dataManip/psMatrixVectorArithmetic.h	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/psMatrixVectorArithmetic.h	(revision 2163)
@@ -0,0 +1,88 @@
+
+/** @file  psMatrixVectorArithmetic.h
+ *
+ *  @brief Provides unary and binary functions for simple matrix and vector element operations. Functions
+ *  include:
+ *
+ *      Addition (+)
+ *      Subtraction (-)
+ *      Multiplication (*)
+ *      Division (/)
+ *      Power (^)
+ *      Minimum (min)
+ *      Maximum (max)
+ *      Absolute value (abs)
+ *      Exponent (exp)
+ *      Natural Log (ln)
+ *      Power of 10 (ten)
+ *      Log (log)
+ *      Sine (sin or dsin)
+ *      Cosine (cos or dcos)
+ *      Tangent (tan or dtan)
+ *      Arcsine (asin or dasin)
+ *      Arccosine (acos or dacos)
+ *      Arctan (atan or datan)
+ *
+ *  Currently only vector-vector and image-image binary operations are supported.
+ *
+ *  @ingroup MatrixVectorArithmetic
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-11 02:37:55 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PSMATRIX_VECTOR_ARITHMETIC_H
+#define PSMATRIX_VECTOR_ARITHMETIC_H
+
+/// @addtogroup MatrixVectorArithmetic
+/// @{
+
+/** Perform simple binary arithmetic with images or vectors
+ *
+ *  Performs addition, subtraction, multiplication, division, power, minumum, and maximum arithmetic
+ *  operations with images and vectors. Uses the form:
+ *
+ *      out = in1 op in2,
+ *
+ *      Where op is: "+", "-", "*", "/", "^", "min", or "max"
+ *
+ *  This function only supports vector-vector or image-image opertions.
+ *
+ *  @return  psType* : Pointer to either psImage or psVector.
+ */
+psType* psBinaryOp(
+    void *out,                         ///< Output type, either psImage or psVector.
+    void *in1,                         ///< First input, either psImage or psVector.
+    char *op,                          ///< Operator.
+    void *in2                          ///< Second input, either psImage or psVector.
+);
+
+/** Perform simple unary arithmetic with images or vectors
+ *
+ *  Performs absolute value, exponent, natural log, power of 10, log, sine, cosine, tangent, arcsine,
+ *  arccosine, or arctan. operations with images and vectors. Uses the form:
+ *
+ *     out = op(in),
+ *
+ *     Where op is: "abs", "exp", "ln", "ten", "log", "sin", "cos", "tan" "asin", "acos", "atan", "dsin",
+ *                  "dcos", dtan", "dasin", "dacos", or "datan".
+ *
+ *  Trigometric Operations with "d" prefix use units of degrees. Those without are in radians.
+ *
+ *  This function only supports vector-vector or image-image opertions.
+ *
+ *  @return  psType* : Pointer to either psImage or psVector.
+ */
+psType* psUnaryOp(
+    void *out,                         ///< Output type, either psImage or psVector.
+    void *in,                          ///< Input, either psImage or psVector.
+    char *op                           ///< Operator.
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/dataManip/psMinimize.c
===================================================================
--- /branches/rel3/psLib/src/dataManip/psMinimize.c	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/psMinimize.c	(revision 2163)
@@ -0,0 +1,1567 @@
+/** @file  psMinimize.c
+ *  \brief basic minimization functions
+ *  @ingroup Math
+ *
+ *  This file will contain functions to minimize an arbitrary function at
+ *  a data point, fit an arbitrary function to a set of data points, and
+ *  fit a 1-D polynomial to a set of data points.
+ *
+ *  @author GLF, MHPCC
+ *
+ *  @version $Revision: 1.58 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 01:44:48 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  XXX: must follow coding name standards on local functions.
+ *
+ *  XXX: Section 4.5.1.1 (predefined functions for Gauss minimization via
+ *       LMM) is not addressed here.  We are waiting for subsequent SDRs
+ *       which will redefine the LMM functions.
+ *
+ */
+/*****************************************************************************/
+/* INCLUDE FILES                                                             */
+/*****************************************************************************/
+#include "psMinimize.h"
+/*****************************************************************************/
+/* DEFINE STATEMENTS                                                         */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* TYPE DEFINITIONS                                                          */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* GLOBAL VARIABLES                                                          */
+/*****************************************************************************/
+static psMinimizeChi2PowellFunc Chi2PowellFunc = NULL;
+static psVector *myValue;
+static psVector *myError;
+
+/*****************************************************************************/
+/* FILE STATIC VARIABLES                                                     */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - LOCAL                                           */
+/*****************************************************************************/
+
+/******************************************************************************
+p_psBuildSums1D(x, polyOrder, sums): this routine calculates the powers of
+input parameter "x" between 0 and input parameter polyOrder.  The result is
+returned as a psVector sums.
+ 
+XXX: change name
+XXX: Use a static vector.
+ *****************************************************************************/
+void p_psBuildSums1D(double x,
+                     int polyOrder,
+                     psVector* sums)
+{
+    int i = 0;
+    double xSum = 0.0;
+
+    if (sums == NULL) {
+        sums = psVectorAlloc(polyOrder, PS_TYPE_F64);
+    }
+
+    if (polyOrder > sums->n) {
+        sums = psVectorRealloc(sums, polyOrder);
+    }
+
+    xSum = 1.0;
+    for (i = 0; i <= polyOrder; i++) {
+        sums->data.F64[i] = xSum;
+        xSum *= x;
+    }
+}
+
+/*****************************************************************************
+CalculateSecondDerivs(): Given a set of x/y vectors corresponding to a
+tabulated function at n points, this routine calculates the second
+derivatives of the interpolating cubic splines at those n points.
+ 
+The first and second derivatives at the endpoints, undefined in the SDR, are
+here defined to be 0.0.  They can be modified via ypo and yp1.
+ 
+This routine assumes that vectors x and y are of the appropriate types/sizes
+(F32).
+ 
+XXX: This algorithm is derived from the Numerical Recipes.
+XXX: use recycled vectors for internal data.
+XXX: do an F64 version?
+ *****************************************************************************/
+float *CalculateSecondDerivs(const psVector* restrict x,        ///< Ordinates (or NULL to just use the indices)
+                             const psVector* restrict y)        ///< Coordinates
+{
+    psTrace(".psLib.dataManip.CalculateSecondDerivs", 4,
+            "---- CalculateSecondDerivs() begin ----\n");
+
+    int i;
+    int k;
+    bool mustFreeX = false;
+    float sig;
+    float p;
+    int n = y->n;
+    float *u = (float *) psAlloc(n * sizeof(float));
+    float *derivs2 = (float *) psAlloc(n * sizeof(float));
+    float *X = (float *) & (x->data.F32[0]);
+    float *Y = (float *) & (y->data.F32[0]);
+    float qn;
+
+    // XXX: The second derivatives at the endpoints, undefined in the SDR,
+    // are set in psConstants.h: LEFT_SPLINE_DERIV, RIGHT_SPLINE_DERIV.
+    derivs2[0] = -0.5;
+    u[0]= (3.0/(X[1]-X[0])) * ((Y[1]-Y[0])/(X[1]-X[0]) - LEFT_SPLINE_DERIV);
+
+    for (i=1;i<=(n-2);i++) {
+        sig = (X[i] - X[i-1]) / (X[i+1] - X[i-1]);
+        p = sig * derivs2[i-1] + 2.0;
+        derivs2[i] = (sig - 1.0) / p;
+        u[i] = ((Y[i+1] - Y[i])/(X[i+1]-X[i])) - ((Y[i]-Y[i-1])/(X[i]-X[i-1]));
+        u[i] = ((6.0 * u[i] / (X[i+1] - X[i-1])) - (sig * u[i-1])) / p;
+
+        psTrace(".psLib.dataManip.CalculateSecondDerivs", 6,
+                "X[%d] is %f\n", i, X[i]);
+        psTrace(".psLib.dataManip.CalculateSecondDerivs", 6,
+                "Y[%d] is %f\n", i, Y[i]);
+        psTrace(".psLib.dataManip.CalculateSecondDerivs", 6,
+                "u[%d] is %f\n", i, u[i]);
+    }
+
+    qn = 0.5;
+    u[n-1] = (3.0/(X[n-1]-X[n-2])) * (RIGHT_SPLINE_DERIV - (Y[n-1]-Y[n-2])/(X[n-1]-X[n-2]));
+    derivs2[n-1] = (u[n-1] - (qn * u[n-2])) / ((qn * derivs2[n-2]) + 1.0);
+
+    for (k=(n-2);k>=0;k--) {
+        derivs2[k] = derivs2[k] * derivs2[k+1] + u[k];
+
+        psTrace(".psLib.dataManip.CalculateSecondDerivs", 6,
+                "derivs2[%d] is %f\n", k, derivs2[k]);
+    }
+
+    if (mustFreeX == true) {
+        psFree(X);
+    }
+    psFree(u);
+
+    psTrace(".psLib.dataManip.CalculateSecondDerivs", 4,
+            "---- CalculateSecondDerivs() end ----\n");
+    return(derivs2);
+}
+
+/******************************************************************************
+p_psNRSpline1DEval(): This routine does NR-style evaluation of cubic splines.
+It takes advantage of the 2nd derivatives of the cubic splines, which are
+stored in the psSPline1D data structure, and computes the interpolated value
+directly, without computing (or using) the interpolating cubic spline
+polynomial.
+ 
+This routine is here mostly for a sanity check on the psLib function
+evalSpline() which computes the interpolated value based on the cubic spline
+polynomials which are stored in psSpline1D.
+ 
+XXX: check types/sizes
+XXX: This is F32 only
+ *****************************************************************************/
+float p_psNRSpline1DEval(psSpline1D *spline,
+                         const psVector* restrict x,
+                         const psVector* restrict y,
+                         float X)
+{
+    int n;
+    int klo;
+    int khi;
+    float H;
+    float A;
+    float B;
+    float C;
+    float D;
+    float Y;
+
+    n = spline->n;
+    klo = p_psVectorBinDisectF32(spline->domains, (spline->n)+1, X);
+    khi = klo + 1;
+    H = (spline->domains)[khi] - (spline->domains)[klo];
+    A = ((spline->domains)[khi] - X) / H;
+    B = (X - (spline->domains)[klo]) / H;
+    C = ((A*A*A)-A) * (H*H/6.0);
+    D = ((B*B*B)-B) * (H*H/6.0);
+
+    Y = (A * y->data.F32[klo]) +
+        (B * y->data.F32[khi]) +
+        (C * (spline->p_psDeriv2)[klo]) +
+        (D * (spline->p_psDeriv2)[khi]);
+
+    return(Y);
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+/*****************************************************************************
+psVectorFitSpline1D(): given a psSpline1D data structure and a set of x/y
+vectors, this routine generates the linear or cublic splines which satisfy
+those data points.
+ 
+The formula for calculating the spline polynomials is derived from Numerical
+Recipes in C.  The basic idea is that the polynomial is
+ (1)     y = (A * y[0]) +
+ (2)         (B * y[1]) +
+ (3)         ((((A*A*A)-A) * mySpline->p_psDeriv2[0]) * H^2)/6.0 +
+ (4)         ((((B*B*B)-B) * mySpline->p_psDeriv2[1]) * H^2)/6.0
+Where:
+ H = x[1]-x[0]
+ A = (x[1]-x)/H
+ B = (x-x[0])/H
+The bulk of the code in this routine is the expansion of the above equation
+into a polynomial in terms of x, and then saving the coefficients of the
+powers of x in the spline polynomials.  This gets pretty complicated.
+ 
+XXX: usage of yErr is not specified in IfA documentation.
+XXX: Is the x argument redundant?  What do we do if the x argument is
+supplied, but does not equal the domains specified in mySpline?
+XXX: can psSpline be NULL?
+ 
+XXX: reimplement this assuming that mySpline is NULL?
+ 
+XXX: What happens if X is NULL, then an index vector is generated for X, but
+that index vector lies outside the range vectors in mySpline?
+ *****************************************************************************/
+psSpline1D *psVectorFitSpline1D(psSpline1D *mySpline,              ///< The spline which will be generated.
+                                const psVector* restrict x,        ///< Ordinates (or NULL to just use the indices)
+                                const psVector* restrict y,        ///< Coordinates
+                                const psVector* restrict yErr)     ///< Errors in coordinates, or NULL
+{
+    psTrace(".psLib.dataManip.psVectorFitSpline1D", 4,
+            "---- psVectorFitSpline1D() begin ----\n");
+    int numSplines = (y->n)-1;
+    float tmp;
+    float H;
+    int i;
+    float slope;
+    psVector *x32 = NULL;
+    psVector *y32 = NULL;
+    psVector *yErr32 = NULL;
+    static psVector *x32Static = NULL;
+    static psVector *y32Static = NULL;
+    static psVector *yErr32Static = NULL;
+
+    PS_CHECK_NULL_PTR_RETURN_NULL(mySpline);
+    PS_CHECK_NULL_PTR_RETURN_NULL(y);
+    VECTOR_CHECK_TYPE_F32_OR_F64_RETURN_NULL(y);
+    CONVERT_VECTOR_F64_TO_F32(y, y32, y32Static);
+
+    // If yErr==NULL, set all errors equal.
+    if (yErr == NULL) {
+        GEN_PERSIST_YERR_VEC_F32(yErr32Static, y->n);
+        yErr32 = yErr32Static;
+    } else {
+        VECTOR_CHECK_TYPE_F32_OR_F64_RETURN_NULL(yErr);
+        CONVERT_VECTOR_F64_TO_F32(yErr, yErr32, yErr32Static);
+    }
+
+    // If x==NULL, create an x32 vector with x values set to (0:n).
+    if (x == NULL) {
+        GEN_PERSIST_X_INDEX_VEC_F32(x32Static, y->n);
+        x32 = x32Static;
+    } else {
+        VECTOR_CHECK_TYPE_F32_OR_F64_RETURN_NULL(x);
+        CONVERT_VECTOR_F64_TO_F32(x, x32, x32Static);
+    }
+    PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(x32, y32);
+    PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(yErr32, y32);
+
+    if (y32->n != (1 + mySpline->n)) {
+        psError(__func__, "data size / spline size mismatch (%d %d)\n",
+                y32->n, mySpline->n);
+        return(NULL);
+    }
+
+    // If these are linear splines, which means their polynomials will have
+    // two coefficients, then we do the simple calculation.
+    if (2 == (mySpline->spline[0])->n) {
+        for (i=0;i<mySpline->n;i++) {
+            slope = (y32->data.F32[i+1] - y32->data.F32[i]) /
+                    (mySpline->domains[i+1] - mySpline->domains[i]);
+            (mySpline->spline[i])->coeff[0] = y32->data.F32[i] -
+                                              (slope * mySpline->domains[i]);
+
+            (mySpline->spline[i])->coeff[1] = slope;
+            psTrace(".psLib.dataManip.psMinimize.psVectorFitSpline1D", 4,
+                    "---- mySpline %d coeffs are (%f, %f)\n", i,
+                    (mySpline->spline[i])->coeff[0],
+                    (mySpline->spline[i])->coeff[1]);
+        }
+        psTrace(".psLib.dataManip.psMinimize.psVectorFitSpline1D", 4,
+                "---- Exiting psVectorFitSpline1D()()\n");
+        return((psSpline1D *) mySpline);
+    }
+
+    // Check if these are cubic splines (n==4).  If not, psError.
+    if (4 != (mySpline->spline[0])->n) {
+        psError(__func__, "Don't know how to generate %d-order splines.",
+                (mySpline->spline[0])->n-1);
+        return(NULL);
+    }
+
+    // If we get here, then we know these are cubic splines.  We first
+    // generate the second derivatives at each data point.
+    mySpline->p_psDeriv2 = CalculateSecondDerivs(x32, y32);
+    for (i=0;i<y32->n;i++)
+        psTrace(".psLib.dataManip.psVectorFitSpline1D", 6,
+                "Second deriv[%d] is %f\n", i, mySpline->p_psDeriv2[i]);
+
+    // We generate the coefficients of the spline polynomials.  I can't
+    // concisely explain how this code works.  See above function comments
+    // and Numerical Recipes in C.
+    for (i=0;i<numSplines;i++) {
+        H = x32->data.F32[i+1] - x32->data.F32[i];
+        psTrace(".psLib.dataManip.psVectorFitSpline1D", 4,
+                "x data (%f - %f) (%f)\n", x->data.F32[i], x->data.F32[i+1], H);
+        //
+        // ******** Calculate 0-order term ********
+        //
+        // From (1)
+        (mySpline->spline[i])->coeff[0] = (y32->data.F32[i] * x32->data.F32[i+1]/H);
+        // From (2)
+        ((mySpline->spline[i])->coeff[0])-= ((y32->data.F32[i+1] * x32->data.F32[i])/H);
+        // From (3)
+        tmp = (x32->data.F32[i+1] * x32->data.F32[i+1] * x32->data.F32[i+1]) / (H * H * H);
+        tmp-= (x32->data.F32[i+1] / H);
+        tmp*= (mySpline->p_psDeriv2)[i] * H * H / 6.0;
+        ((mySpline->spline[i])->coeff[0])+= tmp;
+        // From (4)
+        tmp = -(x32->data.F32[i] * x32->data.F32[i] * x32->data.F32[i]) / (H * H * H);
+        tmp+= (x32->data.F32[i] / H);
+        tmp*= (mySpline->p_psDeriv2)[i+1] * H * H / 6.0;
+        ((mySpline->spline[i])->coeff[0])+= tmp;
+
+        //
+        // ******** Calculate 1-order term ********
+        //
+        // From (1)
+        (mySpline->spline[i])->coeff[1] = -(y32->data.F32[i]) / H;
+        // From (2)
+        ((mySpline->spline[i])->coeff[1])+= (y32->data.F32[i+1] / H);
+        // From (3)
+        tmp = -3.0 * (x32->data.F32[i+1] * x32->data.F32[i+1]) / (H * H * H);
+        tmp+= (1.0 / H);
+        tmp*= ((mySpline->p_psDeriv2)[i]) * H * H / 6.0;
+        ((mySpline->spline[i])->coeff[1])+= tmp;
+        // From (4)
+        tmp = 3.0 * (x32->data.F32[i] * x32->data.F32[i]) / (H * H * H);
+        tmp-= (1.0 / H);
+        tmp*= ((mySpline->p_psDeriv2)[i+1]) * H * H / 6.0;
+        ((mySpline->spline[i])->coeff[1])+= tmp;
+
+        //
+        // ******** Calculate 2-order term ********
+        //
+        // From (3)
+        (mySpline->spline[i])->coeff[2] = ((mySpline->p_psDeriv2)[i]) * 3.0 * x32->data.F32[i+1] / (6.0 * H);
+        // From (4)
+        ((mySpline->spline[i])->coeff[2])-= (((mySpline->p_psDeriv2)[i+1]) * 3.0 * x32->data.F32[i] / (6.0 * H));
+
+        //
+        // ******** Calculate 3-order term ********
+        //
+        // From (3)
+        (mySpline->spline[i])->coeff[3] = -((mySpline->p_psDeriv2)[i]) / (6.0 * H);
+        // From (4)
+        ((mySpline->spline[i])->coeff[3])+=  ((mySpline->p_psDeriv2)[i+1]) / (6.0 * H);
+
+        psTrace(".psLib.dataManip.psVectorFitSpline1D", 6,
+                "(mySpline->spline[%d])->coeff[0] is %f\n", i, (mySpline->spline[i])->coeff[0]);
+        psTrace(".psLib.dataManip.psVectorFitSpline1D", 6,
+                "(mySpline->spline[%d])->coeff[1] is %f\n", i, (mySpline->spline[i])->coeff[1]);
+        psTrace(".psLib.dataManip.psVectorFitSpline1D", 6,
+                "(mySpline->spline[%d])->coeff[2] is %f\n", i, (mySpline->spline[i])->coeff[2]);
+        psTrace(".psLib.dataManip.psVectorFitSpline1D", 6,
+                "(mySpline->spline[%d])->coeff[3] is %f\n", i, (mySpline->spline[i])->coeff[3]);
+
+    }
+
+    psTrace(".psLib.dataManip.psVectorFitSpline1D", 4,
+            "---- psVectorFitSpline1D() end ----\n");
+    return(mySpline);
+}
+
+/******************************************************************************
+psMinimizeLMChi2():  This routine will take an procedure which calculates an
+arbitrary function and it's derivative and minimize the chi-squared match
+between that function at the specified coords and the specified value at
+those coords.
+ 
+XXX: Do this:
+ After checking that all entries in the paramMask are 1 or 0, when
+ forming the A matrix from alpha, try this:
+ 
+     A[i][i] = (1 + lambda*paramask[i]) * alpha[i][i];
+ 
+XXX: This is very different from what is specified in the SDR.  Must
+coordinate with IfA on new SDR.
+ 
+XXX: Do vector/image recycles.
+ 
+XXX: probably yErr will be part of the SDR.
+ 
+XXX: This must work for both F32 and F64.  F32 is currently implemented.
+     Note: since the LUD routines are only implemented in F64, then we
+     will have to convert all F32 input vectors to F64 regardless.  So,
+     the F64 port might be.
+ *****************************************************************************/
+bool psMinimizeLMChi2(psMinimization *min,
+                      psVector *params,
+                      const psVector *paramMask,
+                      psImage *covar,
+                      const psArray *coords,
+                      const psVector *value,
+                      psMinimizeLMChi2Func func)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(min);
+    PS_CHECK_NULL_VECTOR_RETURN_NULL(params);
+    PS_CHECK_EMPTY_VECTOR_RETURN_NULL(params);
+    PS_CHECK_NULL_PTR_RETURN_NULL(coords);
+    PS_CHECK_NULL_VECTOR_RETURN_NULL(value);
+    PS_CHECK_EMPTY_VECTOR_RETURN_NULL(value);
+    if (paramMask != NULL) {
+        PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(params, paramMask);
+    }
+    psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
+            "---- psMinimizeLMChi2() begin ----\n");
+    int numData = value->n;
+    int numParams = params->n;
+    int i;
+    int j;
+    int k;
+    int l;
+    int n;
+    int p;
+    psVector *beta = psVectorAlloc(numParams, PS_TYPE_F64);
+    psVector *perm = psVectorAlloc(numParams, PS_TYPE_F64);
+
+    psVector *paramDeltasF64 = psVectorAlloc(numParams, PS_TYPE_F64);
+    psVector *origParams = psVectorAlloc(numParams, PS_TYPE_F32);
+    psVector *newParams = psVectorAlloc(numParams, PS_TYPE_F32);
+
+    psImage *alpha = psImageAlloc(numParams, numParams, PS_TYPE_F32);
+    psImage *A = psImageAlloc(numParams, numParams, PS_TYPE_F64);
+    psImage *aOut = psImageAlloc(numParams, numParams, PS_TYPE_F64);
+
+    psVector **deriv = (psVector **) psAlloc(numData * sizeof(psVector *));
+    for (i=0;i<numData;i++) {
+        deriv[i] = psVectorAlloc(numParams, PS_TYPE_F32);
+    }
+
+    psVector *currValueVec = psVectorAlloc(value->n, PS_TYPE_F32);
+    psVector *newValueVec = psVectorAlloc(value->n, PS_TYPE_F32);
+
+    float currChi2 = 0.0;
+    float newChi2 = 0.0;
+    float lamda = 0.00005;
+
+    psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
+            "min->maxIter is %d\n", min->maxIter);
+    psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
+            "min->tol is %f\n", min->tol);
+
+    for (p=0;p<numParams;p++) {
+        origParams->data.F32[p] = params->data.F32[p];
+    }
+
+    min->lastDelta = HUGE;
+    min->iter = 0;
+
+    while ((min->lastDelta > min->tol) && (min->iter < min->maxIter)) {
+        psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
+                "------------------------------------------------------\n");
+        psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
+                "Iteration %d.  Delta is %f\n", min->iter, min->lastDelta);
+
+        //
+        // Calculate the current values and chi-squared of the function.
+        //
+        currChi2 = 0.0;
+        for (n=0;n<numData;n++) {
+            currValueVec->data.F32[n] = func(deriv[n],
+                                             params,
+                                             (psVector *) coords->data[n]);
+            currChi2+= (currValueVec->data.F32[n] * currValueVec->data.F32[n]);
+        }
+
+        for (p=0;p<numParams;p++) {
+            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
+                    "params->data.F32[%d] is %f.\n", p, params->data.F32[p]);
+        }
+        psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
+                "Current chi-squared is (%f)\n", currChi2);
+
+        //
+        // Mask elements of the derivative for each data point.
+        //
+        for (p=0;p<numParams;p++) {
+            if ((paramMask != NULL) && (paramMask->data.U8[p] != 0)) {
+                for (n=0;n<numData;n++) {
+                    (deriv[n])->data.F32[p] = 0.0;
+                }
+            }
+        }
+
+        //
+        // Calculate the BETA vector.
+        //
+        for (p=0;p<numParams;p++) {
+            beta->data.F64[p] = 0.0;
+            for (n=0;n<numData;n++) {
+                (beta->data.F64[p])+=
+                    (value->data.F32[n] - currValueVec->data.F32[n]) *
+                    (deriv[n])->data.F32[p];
+            }
+            // XXX: multiple by -1 here?
+            (beta->data.F64[p])*= -1.0;
+            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
+                    "beta->data.F64[%d] is %f.\n", p, beta->data.F64[p]);
+        }
+
+        //
+        // Calculate the ALPHA matrix.
+        //
+        for (k=0;k<numParams;k++) {
+            for (l=0;l<numParams;l++) {
+                alpha->data.F32[k][l] = 0.0;
+                for (n=0;n<numData;n++) {
+                    alpha->data.F32[k][l]+= (deriv[n])->data.F32[k] *
+                                            (deriv[n])->data.F32[l];
+                }
+            }
+        }
+
+        //
+        // Calculate the matrix A.
+        //
+        for (j=0;j<numParams;j++) {
+            for (k=0;k<numParams;k++) {
+                if (j == k) {
+                    A->data.F64[j][k] =
+                        (double) ((1.0 + lamda) * alpha->data.F32[j][k]);
+                } else {
+                    A->data.F64[j][k] = (double) alpha->data.F32[j][k];
+                }
+            }
+        }
+        for (j=0;j<numParams;j++) {
+            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "Matrix A[][]:\n");
+            for (k=0;k<numParams;k++) {
+                psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "%f ", A->data.F64[j][k]);
+            }
+            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "Matrix A[][]:\n");
+        }
+
+        //
+        // Solve A * alpha = Beta
+        //
+        aOut = psMatrixLUD(aOut, perm, A);
+        paramDeltasF64 = psMatrixLUSolve(paramDeltasF64, aOut, beta, perm);
+
+        //
+        // Mask any masked parameters.
+        //
+        for (i=0;i<numParams;i++) {
+            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
+                    "paramDeltasF64->data.F64[%d] is %f.\n", i, paramDeltasF64->data.F64[i]);
+            if ((paramMask != NULL) && (paramMask->data.U8[i] != 0)) {
+                newParams->data.F32[i] = origParams->data.F32[i];
+            } else {
+                newParams->data.F32[i] = params->data.F32[i] -
+                                         (float) paramDeltasF64->data.F64[i];
+            }
+        }
+
+        psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
+                "Calling func() with new parameters:\n");
+        for (i=0;i<numParams;i++) {
+            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
+                    "newParams->data.F32[%d] is %f.\n", i, newParams->data.F32[i]);
+        }
+
+
+        //
+        // Calculate new function values.
+        //
+        newChi2 = 0.0;
+        for (n=0;n<numData;n++) {
+            newValueVec->data.F32[n] = func(deriv[n], newParams,
+                                            (psVector *) coords->data[n]);
+            newChi2+= (newValueVec->data.F32[n] * newValueVec->data.F32[n]);
+        }
+        psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
+                "old/new chi-squareds are (%f, %f)\n", currChi2, newChi2);
+
+        //
+        // If the new chi-squared is lower, then keep it.
+        //
+        if (currChi2 > newChi2) {
+            min->lastDelta = currChi2 - newChi2;
+            min->value = newChi2;
+
+            // We already masked params.
+            for (i=0;i<numParams;i++) {
+                params->data.F32[i] = (float) newParams->data.F32[i];
+            }
+            lamda*= 0.1;
+        } else {
+            lamda*= 10.0;
+        }
+        psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
+                "lamda is %f\n", lamda);
+        min->iter++;
+    }
+    psFree(beta);
+    psFree(perm);
+    psFree(paramDeltasF64);
+    psFree(origParams);
+    psFree(newParams);
+    psFree(alpha);
+    psFree(A);
+    psFree(aOut);
+    for (i=0;i<numData;i++) {
+        psFree(deriv[i]);
+    }
+    psFree(deriv);
+    psFree(currValueVec);
+    psFree(newValueVec);
+
+    if ((min->iter < min->maxIter) ||
+            (min->lastDelta <= min->tol)) {
+        return(true);
+    }
+
+    psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
+            "---- psMinimizeLMChi2() end (false) ----\n");
+    return(false);
+}
+
+/******************************************************************************
+p_psVectorFitPolynomial1DCheb():  This routine will fit a Chebyshev
+polynomial of degree myPoly to the data points (x, y) and return the
+coefficients of that polynomial.
+ 
+XXX: yErr is currently ignored.
+ 
+XXX: Use private name?
+*****************************************************************************/
+psPolynomial1D *p_psVectorFitPolynomial1DCheby(psPolynomial1D* myPoly,
+        const psVector* restrict x,
+        const psVector* restrict y,
+        const psVector* restrict yErr)
+{
+    int j;
+    int k;
+    int n = x->n;
+    double fac;
+    double sum;
+    GEN_STATIC_RECYCLED_VECTOR(f, n, PS_TYPE_F64);
+    psScalar *fScalar;
+    psScalar tmpScalar;
+    tmpScalar.type.type = PS_TYPE_F64;
+
+    // XXX: These assignments appear too simple to warrant code and
+    // variable declarations.  I retain them here to maintain coherence
+    // with the NR code.
+    double min = -1.0;
+    double max = 1.0;
+    double bma = 0.5 * (max-min);  // 1
+    double bpa = 0.5 * (max+min);  // 0
+
+    // In this loop, we first calculate the values of X for which the
+    // Chebyshev polynomials are zero (see NR, section 5.4).  Then we
+    // calculate the value of the function we are fitting the Chebyshev
+    // polynomials to at those values of X.  This is a bit tricky since
+    // we don't know that function.  So, we instead do 3-order LaGrange
+    // interpolation at the point X for the psVectors x,y for which we
+    // are fitting this ChebyShev polynomial to.
+
+    for (int i=0;i<n;i++) {
+        // NR 5.8.4
+        double Y = cos(M_PI * (0.5 + ((float) i)) / ((float) n));
+        double X = (Y + bma + bpa) - 1.0;
+        tmpScalar.data.F64 = X;
+
+        // We interpolate against are tabluated x,y vectors to determine the
+        // function value at X.
+        fScalar = p_psVectorInterpolate((psVector *) x,
+                                        (psVector *) y,
+                                        3,
+                                        &tmpScalar);
+
+        f->data.F64[i] = fScalar->data.F64;
+        psFree(fScalar);
+
+        psTrace(".psLib.dataManip.p_psVectorFitPolynomial1DCheby", 6,
+                "(x, X, y, f(X)) is (%f, %f, %f, %f)\n",
+                x->data.F64[i], X, y->data.F64[i], f->data.F64[i]);
+    }
+
+    // We have the values for f() at the zero points, we now calculate the
+    // coefficients of the Chebyshev polynomial: NR 5.8.7.
+
+    fac = 2.0/((float) n);
+    // XXX: is this loop bound correct?
+    for (j=0;j<myPoly->n;j++) {
+        sum = 0.0;
+        for (k=0;k<n;k++) {
+            sum+= f->data.F64[k] *
+                  cos(M_PI * ((float) j) * (0.5 + ((float) k)) / ((float) n));
+        }
+
+        myPoly->coeff[j] = fac * sum;
+    }
+
+    return(myPoly);
+}
+
+/******************************************************************************
+p_psVectorFitPolynomial1DOrd():  This routine will fit an ordinary
+polynomial of degree myPoly to the data points (x, y) and return the
+coefficients of that polynomial.
+ 
+XXX: Use private name?
+XXX: Use recycled vectors.
+ *****************************************************************************/
+psPolynomial1D* p_psVectorFitPolynomial1DOrd(psPolynomial1D* myPoly,
+        const psVector* restrict x,
+        const psVector* restrict y,
+        const psVector* restrict yErr)
+{
+    int polyOrder = myPoly->n;
+    psImage* A = NULL;
+    psImage* ALUD = NULL;
+    psVector* B = NULL;
+    psVector* outPerm = NULL;
+    psVector* X = NULL;         // NOTE: do we need this?
+    psVector* coeffs = NULL;
+    int i = 0;
+    int j = 0;
+    int k = 0;
+    psVector* xSums = NULL;
+
+    psTrace(".psLib.dataManip.psVectorFitPolynomial1D", 4,
+            "---- psVectorFitPolynomial1D() begin ----\n");
+    // printf("psVectorFitPolynomial1D()\n");
+    // for (i=0;i<x->n;i++) {
+    // printf("(x, y, yErr) is (%f, %f, %f)\n", x->data.F64[i], y->data.F64[i], yErr->data.F64[i]);
+    // }
+
+    A = psImageAlloc(polyOrder, polyOrder, PS_TYPE_F64);
+    ALUD = psImageAlloc(polyOrder, polyOrder, PS_TYPE_F64);
+    B = psVectorAlloc(polyOrder, PS_TYPE_F64);
+    coeffs = psVectorAlloc(polyOrder, PS_TYPE_F64);
+    X = psVectorAlloc(x->n, PS_TYPE_F64);
+    outPerm = psVectorAlloc(polyOrder, PS_TYPE_F64);
+    xSums = psVectorAlloc(1 + 2 * polyOrder, PS_TYPE_F64);
+
+    // Initialize data structures.
+    for (i = 0; i < polyOrder; i++) {
+        B->data.F64[i] = 0.0;
+        coeffs->data.F64[i] = 0.0;
+        outPerm->data.F64[i] = 0.0;
+        for (j = 0; j < polyOrder; j++) {
+            A->data.F64[i][j] = 0.0;
+            ALUD->data.F64[i][j] = 0.0;
+        }
+    }
+    for (i = 0; i < X->n; i++) {
+        X->data.F64[i] = x->data.F64[i];
+    }
+
+    // Build the B and A data structs.
+    if (yErr == NULL) {
+        for (i = 0; i < X->n; i++) {
+            p_psBuildSums1D(X->data.F64[i], 2 * polyOrder, xSums);
+
+            for (k = 0; k < polyOrder; k++) {
+                B->data.F64[k] += y->data.F64[i] * xSums->data.F64[k];
+            }
+
+            for (k = 0; k < polyOrder; k++) {
+                for (j = 0; j < polyOrder; j++) {
+                    A->data.F64[k][j] += xSums->data.F64[k + j];
+                }
+            }
+        }
+    } else {
+        for (i = 0; i < X->n; i++) {
+            p_psBuildSums1D(X->data.F64[i], 2 * polyOrder, xSums);
+
+            for (k = 0; k < polyOrder; k++) {
+                B->data.F64[k] += y->data.F64[i] * xSums->data.F64[k] /
+                                  yErr->data.F64[i];
+            }
+
+            for (k = 0; k < polyOrder; k++) {
+                for (j = 0; j < polyOrder; j++) {
+                    A->data.F64[k][j] += xSums->data.F64[k + j] /
+                                         yErr->data.F64[i];
+                }
+            }
+        }
+    }
+
+    ALUD = psMatrixLUD(ALUD, outPerm, A);
+    coeffs = psMatrixLUSolve(coeffs, ALUD, B, outPerm);
+
+    for (k = 0; k < polyOrder; k++) {
+        myPoly->coeff[k] = coeffs->data.F64[k];
+        // printf("myPoly->coeff[%d] is %f\n", k, myPoly->coeff[k]);
+    }
+
+    // for (i=0;i<x->n;i++) {
+    // printf("HMMM: psEvalPolynomial1D(%f) is %f\n", x->data.F64[i], psEvalPolynomial1D(x->data.F64[i],
+    // myPoly));
+    // }
+
+    psFree(A);
+    psFree(ALUD);
+    psFree(B);
+    psFree(coeffs);
+    psFree(X);
+    psFree(outPerm);
+    psFree(xSums);
+
+    psTrace(".psLib.dataManip.psVectorFitPolynomial1D", 4,
+            "---- psVectorFitPolynomial1D() begin ----\n");
+    return (myPoly);
+}
+
+/******************************************************************************
+psVectorFitPolynomial1D():  This routine must fit a polynomial of degree
+myPoly to the data points (x, y) and return the coefficients of that
+polynomial.
+ 
+XXX: type F32 is done via vector conversion only.
+ *****************************************************************************/
+psPolynomial1D* psVectorFitPolynomial1D(psPolynomial1D* myPoly,
+                                        const psVector* restrict x,
+                                        const psVector* restrict y,
+                                        const psVector* restrict yErr)
+{
+    int i;
+    psPolynomial1D *tmpPoly;
+    PS_CHECK_NULL_1DPOLY_RETURN_NULL(myPoly);
+    PS_CHECK_NULL_VECTOR_RETURN_NULL(y);
+    PS_CHECK_EMPTY_VECTOR_RETURN_NULL(y);
+    psVector *x64 = NULL;
+    psVector *y64 = NULL;
+    psVector *yErr64 = NULL;
+    static psVector *x64Static = NULL;
+    static psVector *y64Static = NULL;
+    static psVector *yErr64Static = NULL;
+
+    VECTOR_CHECK_TYPE_F32_OR_F64_RETURN_NULL(y);
+    CONVERT_VECTOR_F32_TO_F64(y, y64, y64Static);
+
+    // If yErr==NULL, set all errors equal.
+    if (yErr == NULL) {
+        GEN_PERSIST_YERR_VEC_F64(yErr64Static, y->n);
+        yErr64 = yErr64Static;
+    } else {
+        VECTOR_CHECK_TYPE_F32_OR_F64_RETURN_NULL(yErr);
+        CONVERT_VECTOR_F32_TO_F64(yErr, yErr64, yErr64Static);
+    }
+
+    // If x==NULL, create an x64 vector with x values set to (0:n).
+    if (x == NULL) {
+        GEN_PERSIST_X_INDEX_VEC_F64(x64Static, y->n);
+        if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+            p_psNormalizeVector(x64Static);
+        }
+        x64 = x64Static;
+    } else {
+        VECTOR_CHECK_TYPE_F32_OR_F64_RETURN_NULL(x);
+        CONVERT_VECTOR_F32_TO_F64(x, x64, x64Static);
+    }
+    PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(x64, y64);
+    PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(yErr64, y64);
+
+    // Call the appropriate vector fitting routine.
+    if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        p_psVectorFitPolynomial1DCheby(myPoly, x64, y64, yErr64);
+    } else if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        tmpPoly = p_psVectorFitPolynomial1DOrd(myPoly, x64, y64, yErr64);
+    } else {
+        psError(__func__, "unknown polynomial type.\n");
+        return(NULL);
+    }
+
+    return(myPoly);
+}
+
+
+
+/******************************************************************************
+ *****************************************************************************/
+psMinimization *psMinimizationAlloc(int maxIter,
+                                    float tol)
+{
+    psMinimization *min = psAlloc(sizeof(psMinimization));
+    min->maxIter = maxIter;
+    min->tol = tol;
+    min->value = 0.0;
+    min->iter = 0;
+    min->lastDelta = 0.0;
+
+    return(min);
+}
+
+/******************************************************************************
+p_psDetermineBracket():  This routine takes as input an arbitrary function,
+and the parameter to vary, and the line along which it must vary.  This
+function produces as output a bracket [a, b, c] such that
+ 
+        f(param + b * line) is less than f(param + a * line) and
+                                         f(param + c * line).
+ 
+Algorithm: XXX completely ad hoc: start with the user-supplied starting
+parameter and call that b.  Calculate a/c as a fractional amount
+smaller/larger than b.  Repeat this process until a local minimum is found.
+ 
+XXX: new algorithm: start at x=0, expand in one direction until the function
+decreases.  Then you have two points in the bracket.  Keep going until it
+increases, or x is too large.  If thst does not work, expand in the other
+direction.
+ 
+XXX: This is F32 only
+ *****************************************************************************/
+psVector *p_psDetermineBracket(psVector *params,
+                               psVector *line,
+                               const psVector *paramMask,
+                               const psArray *coords,
+                               psMinimizePowellFunc func)
+{
+    float a = 0.0;
+    float b = 0.0;
+    float c = 0.0;
+    float fa = 0.0;
+    float fb = 0.0;
+    float fc = 0.0;
+    int iter = 100;
+    float aDir = 0.0;
+    float cDir = 0.0;
+    float new_aDir = 0.0;
+    float new_cDir = 0.0;
+    psVector *bracket = psVectorAlloc(3, PS_TYPE_F32);
+    float stepSize = DETERMINE_BRACKET_STEP_SIZE;
+    psVector *tmp = NULL;
+    int i = 0;
+    int null = 0;
+
+    psTrace(".psLib.dataManip.p_psDetermineBracket", 4,
+            "---- p_psDetermineBracket() begin ----\n");
+
+    for (i=0;i<params->n;i++) {
+        if (paramMask->data.U8[i] == 0) {
+            if (line->data.F32[i] >= FLT_EPSILON) {
+                null = 1;
+            }
+        }
+    }
+
+    if (null == 0) {
+        psTrace(".psLib.dataManip.p_psDetermineBracket", 2,
+                "p_psDetermineBracket() called with zero line vector.\n");
+        psTrace(".psLib.dataManip.p_psDetermineBracket", 4,
+                "---- p_psDetermineBracket() end (NULL) ----\n");
+        psFree(bracket);
+        return(NULL);
+    }
+
+    tmp = psVectorAlloc(params->n, PS_TYPE_F32);
+
+    b = 0;
+    a = -stepSize;
+    c = stepSize;
+
+    for (i=0;i<params->n;i++) {
+        if (paramMask->data.U8[i] == 0) {
+            tmp->data.F32[i] = params->data.F32[i] + (a * line->data.F32[i]);
+        } else {
+            tmp->data.F32[i] = params->data.F32[i];
+        }
+    }
+    fa = func(tmp, coords);
+
+    for (i=0;i<params->n;i++) {
+        if (paramMask->data.U8[i] == 0) {
+            tmp->data.F32[i] = params->data.F32[i] + (b * line->data.F32[i]);
+        } else {
+            tmp->data.F32[i] = params->data.F32[i];
+        }
+    }
+    fb = func(tmp, coords);
+
+    for (i=0;i<params->n;i++) {
+        if (paramMask->data.U8[i] == 0) {
+            tmp->data.F32[i] = params->data.F32[i] + (c * line->data.F32[i]);
+        } else {
+            tmp->data.F32[i] = params->data.F32[i];
+        }
+    }
+    fc = func(tmp, coords);
+
+    if (fa < fb) {
+        aDir = -1;
+    } else {
+        aDir = 1;
+    }
+
+    if (fc < fb) {
+        cDir = -1;
+    } else {
+        cDir = 1;
+    }
+
+    psTrace(".psLib.dataManip.p_psDetermineBracket", 6,
+            "(a, b, c) is (%f %f %f) (fa, fb, fc) is (%f %f %f)\n", a, b, c, fa, fb, fc);
+
+    while (iter > 0) {
+        psTrace(".psLib.dataManip.p_psDetermineBracket", 6,
+                "psDetermineBracket(): iteration %d\n", iter);
+        if ((fb < fa) && (fb < fc)) {
+            bracket->data.F32[0] = a;
+            bracket->data.F32[1] = b;
+            bracket->data.F32[2] = c;
+            psFree(tmp);
+            psTrace(".psLib.dataManip.p_psDetermineBracket", 6,
+                    "---- p_psDetermineBracket() end ----\n");
+            return(bracket);
+        }
+        stepSize*= (1.0 + stepSize);
+        a =- stepSize;
+        c =+ stepSize;
+
+        for (i=0;i<params->n;i++) {
+            if (paramMask->data.U8[i] == 0) {
+                tmp->data.F32[i] = params->data.F32[i] + (a * line->data.F32[i]);
+            } else {
+                tmp->data.F32[i] = params->data.F32[i];
+            }
+        }
+        fa = func(tmp, coords);
+
+        for (i=0;i<params->n;i++) {
+            if (paramMask->data.U8[i] == 0) {
+                tmp->data.F32[i] = params->data.F32[i] + (c * line->data.F32[i]);
+            } else {
+                tmp->data.F32[i] = params->data.F32[i];
+            }
+        }
+        fc = func(tmp, coords);
+
+        psTrace(".psLib.dataManip.p_psDetermineBracket", 6,
+                "Iter(%d): (a, b, c) is (%f %f %f) (fa, fb, fc) is (%f %f %f)\n", iter, a, b, c, fa, fb, fc);
+
+        if (fa < fb) {
+            new_aDir = -1;
+        } else {
+            new_aDir = 1;
+        }
+
+        if (fc < fb) {
+            new_cDir = -1;
+        } else {
+            new_cDir = 1;
+        }
+        if ((new_aDir == 1) && (aDir == -1)) {
+            bracket->data.F32[0] = a;
+            bracket->data.F32[1] = b;
+            bracket->data.F32[2] = c;
+            psFree(tmp);
+            psTrace(".psLib.dataManip.p_psDetermineBracket", 4,
+                    "---- p_psDetermineBracket() end ----\n");
+            return(bracket);
+        }
+
+        if ((new_cDir == 1) && (cDir == -1)) {
+            bracket->data.F32[0] = a;
+            bracket->data.F32[1] = b;
+            bracket->data.F32[2] = c;
+            psFree(tmp);
+            psTrace(".psLib.dataManip.p_psDetermineBracket", 4,
+                    "---- p_psDetermineBracket() end ----\n");
+            return(bracket);
+        }
+        aDir = new_aDir;
+        cDir = new_cDir;
+        iter--;
+    }
+    psFree(tmp);
+    psFree(bracket);
+    psTrace(".psLib.dataManip.p_psDetermineBracket", 4,
+            "---- p_psDetermineBracket() end (NULL) ----\n");
+    return(NULL);
+}
+
+/******************************************************************************
+This routine takes as input a possibly multi-dimensional function, along
+with an initial guess at the parameters of that function and vector "line"
+of the same size as the parameter vector.  It will minimize the function
+along that vector anr returns the offset along that vector at which the
+minimum is determined.
+ 
+XXX: This routine is not very efficient in terms of total evaluations of the
+function.
+XXX: This is F32 only
+ *****************************************************************************/
+float p_psLineMin(psMinimization *min,
+                  psVector *params,
+                  psVector *line,
+                  const psVector *paramMask,
+                  const psArray *coords,
+                  psMinimizePowellFunc func)
+{
+    psVector *bracket;
+    float a = 0.0;
+    float b = 0.0;
+    float c = 0.0;
+    float n = 0.0;
+    float fa = 0.0;
+    float fb = 0.0;
+    float fc = 0.0;
+    float fn = 0.0;
+    float mul = 0.0;
+    psVector *tmpa = NULL;
+    psVector *tmpb = NULL;
+    psVector *tmpc = NULL;
+    psVector *tmpn = NULL;
+    int i = 0;
+    int null = 0;
+
+    psTrace(".psLib.dataManip.p_psLineMin", 4,
+            "---- p_psLineMin() begin ----\n");
+    psTrace(".psLib.dataManip.p_psLineMin", 6,
+            "min->maxIter is %d\n", min->maxIter);
+    psTrace(".psLib.dataManip.p_psLineMin", 6,
+            "min->tol is %f\n", min->tol);
+
+    if (paramMask != NULL) {
+        for (i=0;i<params->n;i++) {
+            if (paramMask->data.U8[i] == 0) {
+                if (line->data.F32[i] >= FLT_EPSILON) {
+                    null = 1;
+                    psTrace(".psLib.dataManip.p_psLineMin", 4,
+                            "line->data.F32[%d] is %f\n", i, line->data.F32[i]);
+                }
+            }
+        }
+    } else {
+        for (i=0;i<params->n;i++) {
+            if (line->data.F32[i] >= FLT_EPSILON) {
+                null = 1;
+                psTrace(".psLib.dataManip.p_psLineMin", 4,
+                        "line->data.F32[%d] is %f\n", i, line->data.F32[i]);
+            }
+        }
+    }
+
+    if (null == 0) {
+        psTrace(".psLib.dataManip.p_psLineMin", 2,
+                "p_psLineMin() called with zero line vector.\n");
+        return(0.0);
+    }
+
+    tmpa = psVectorAlloc(params->n, PS_TYPE_F32);
+    tmpb = psVectorAlloc(params->n, PS_TYPE_F32);
+    tmpc = psVectorAlloc(params->n, PS_TYPE_F32);
+    tmpn = psVectorAlloc(params->n, PS_TYPE_F32);
+
+    for (i=0;i<params->n;i++) {
+        psTrace(".psLib.dataManip.p_psLineMin", 6,
+                "params, paramMask, line [%d] is (%f %d %f)\n", i,
+                params->data.F32[i],
+                paramMask->data.U8[i],
+                line->data.F32[i]);
+    }
+
+    bracket = p_psDetermineBracket(params, line, paramMask, coords, func);
+    if (bracket == NULL) {
+        psFree(tmpa);
+        psFree(tmpb);
+        psFree(tmpc);
+        psFree(tmpn);
+        psAbort(__func__, "(1) Could not bracket minimum.");
+    }
+
+    min->iter = 0;
+    while (min->iter < min->maxIter) {
+        min->iter++;
+        psTrace(".psLib.dataManip.p_psLineMin", 6,
+                "p_psLineMin(): iteration %d\n", min->iter);
+
+        a = bracket->data.F32[0];
+        b = bracket->data.F32[1];
+        c = bracket->data.F32[2];
+
+        for (i=0;i<params->n;i++) {
+            if (paramMask->data.U8[i] == 0) {
+                tmpa->data.F32[i] = params->data.F32[i] + (a * line->data.F32[i]);
+                tmpb->data.F32[i] = params->data.F32[i] + (b * line->data.F32[i]);
+                tmpc->data.F32[i] = params->data.F32[i] + (c * line->data.F32[i]);
+            } else {
+                tmpa->data.F32[i] = params->data.F32[i];
+                tmpb->data.F32[i] = params->data.F32[i];
+                tmpc->data.F32[i] = params->data.F32[i];
+            }
+        }
+        fa = func(tmpa, coords);
+        fb = func(tmpb, coords);
+        fc = func(tmpc, coords);
+        psTrace(".psLib.dataManip.p_psLineMin", 6,
+                "Iteration %d: f(%f %f %f) is (%f %f %f)\n", min->iter,
+                a, b, c, fa, fb, fc);
+
+        // We determine which is the biggest segment in [a,b,c] then split
+        // that with the point n.
+        if ((b-a) > (c-b)) {
+            // This is the golden section formula
+            n = a + (0.69 * (b-a));
+            for (i=0;i<params->n;i++) {
+                tmpn->data.F32[i] = params->data.F32[i] + (n * line->data.F32[i]);
+            }
+            fn = func(tmpn, coords);
+
+            if (fn > fb) {
+                // a = n, b = b, c = c
+                bracket->data.F32[0] = n;
+            } else {
+                // a = a, b = n, c = b
+                bracket->data.F32[1] = n;
+                bracket->data.F32[2] = b;
+            }
+        } else {
+            n = b + (0.69 * (c-b));
+            for (i=0;i<params->n;i++) {
+                tmpn->data.F32[i] = params->data.F32[i] + (n * line->data.F32[i]);
+            }
+            fn = func(tmpn, coords);
+
+            if (fn > fb) {
+                // a = a, b = b, c = n
+                bracket->data.F32[2] = n;
+            } else {
+                // a = b, b = n, c = c
+                bracket->data.F32[0] = b;
+                bracket->data.F32[1] = n;
+            }
+        }
+        psTrace(".psLib.dataManip.p_psLineMin", 6,
+                "Iteration %d: new bracket is (%f %f %f)\n", min->iter, bracket->data.F32[0], bracket->data.F32[1], bracket->data.F32[2]);
+
+        mul = bracket->data.F32[1];
+        if ((fabs(a-b) < min->tol) && (fabs(b-c) < min->tol)) {
+            for (i=0;i<params->n;i++) {
+                if (paramMask->data.U8[i] == 0) {
+                    params->data.F32[i]+= mul * line->data.F32[i];
+                }
+            }
+            min->value = func(params, coords);
+            psFree(bracket);
+            psFree(tmpa);
+            psFree(tmpb);
+            psFree(tmpc);
+            psFree(tmpn);
+            psTrace(".psLib.dataManip.p_psLineMin", 4,
+                    "---- p_psLineMin() end.a (%f) ----\n", mul);
+            return(mul);
+        }
+    }
+
+    psFree(bracket);
+    psFree(tmpa);
+    psFree(tmpb);
+    psFree(tmpc);
+    psFree(tmpn);
+
+    psTrace(".psLib.dataManip.p_psLineMin", 4,
+            "---- p_psLineMin() end.b (0.0) ----\n");
+    return(0.0);
+}
+
+
+/******************************************************************************
+This routine must minimize a possibly multi-dimensional function.  The
+function to be minimized "func" is:
+    float func(psVector *params, psArray *coords)
+The "params" are the parameters of the function which are varied.  The data
+points at which the function is varied are in the argument "coords" which is
+a psArray of psVectors: each vector represents a different coordinate.
+ 
+XXX: We do not use Brent's method.
+ 
+XXX: The SDR is silent about data types.  F32 is implemented here.
+ 
+XXX: Define constants for default dummy number of iterations and tolerance.
+ 
+XXX: Must define behavior on various NULL inputs.
+ 
+XXX: Check for F32 types?
+ *****************************************************************************/
+bool psMinimizePowell(psMinimization *min,
+                      psVector *params,
+                      const psVector *paramMask,
+                      const psArray *coords,
+                      psMinimizePowellFunc func)
+{
+    PS_CHECK_NULL_VECTOR_RETURN_NULL(params);
+    PS_CHECK_EMPTY_VECTOR_RETURN_NULL(params);
+    PS_CHECK_NULL_PTR_RETURN_NULL(min);
+    PS_CHECK_NULL_PTR_RETURN_NULL(coords);
+    PS_CHECK_NULL_PTR_RETURN_NULL(func);
+
+    int numDims = params->n;
+    int i = 0;
+    int j = 0;
+    psVector **v = NULL;
+    psVector *pQP = NULL;
+    psVector *Q = NULL;
+    psVector *u = NULL;
+    psVector *myParamMask = NULL;  // XXX: Use a recylced vector here.
+    psMinimization dummyMin;
+    float mul = 0.0;
+    float baseFuncVal = 0.0;
+    float currFuncVal = 0.0;
+    int biggestIter = 0;
+    float biggestDiff = 0.0;
+    float term1 = 0.0;
+    float term2 = 0.0;
+    float fqp = 0.0;
+    float diff = 0.0;
+
+    psTrace(".psLib.dataManip.psMinimizePowell", 4,
+            "---- psMinimizePowell() begin ----\n");
+    psTrace(".psLib.dataManip.psMinimizePowell", 6,
+            "min->maxIter is %d\n", min->maxIter);
+    psTrace(".psLib.dataManip.psMinimizePowell", 6,
+            "min->tol is %f\n", min->tol);
+
+    pQP = psVectorAlloc(numDims, PS_TYPE_F32);
+    u = psVectorAlloc(numDims, PS_TYPE_F32);
+    Q = psVectorAlloc(numDims, PS_TYPE_F32);
+
+    if (paramMask == NULL) {
+        myParamMask = psVectorAlloc(params->n, PS_TYPE_U8);
+        for (i=0;i<myParamMask->n;i++) {
+            myParamMask->data.U8[i] = 0;
+        }
+    } else {
+        myParamMask = (psVector *) paramMask;
+    }
+    PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(params, myParamMask);
+
+    // 1: Set v[i] to be the unit vectors for each dimension in params
+    v = (psVector **) psAlloc(params->n * sizeof(psVector **));
+    for (i=0;i<numDims;i++) {
+        v[i] = psVectorAlloc(numDims, PS_TYPE_F32);
+        for (j=0;j<numDims;j++) {
+            if (i == j) {
+                v[i]->data.F32[j] = 1.0;
+            } else {
+                v[i]->data.F32[j] = 0.0;
+            }
+        }
+    }
+
+    // 2: Set Q to be the initial params (P in the ADD)
+    for (i=0;i<numDims;i++) {
+        if (myParamMask->data.U8[i] == 0) {
+            Q->data.F32[i] = params->data.F32[i];
+        }
+    }
+
+    min->iter = 0;
+    while (min->iter < min->maxIter) {
+        min->iter++;
+        psTrace(".psLib.dataManip.psMinimizePowell", 6,
+                "psMinimizePowell() iteration %d\n", min->iter);
+
+        // 3: For each dimension in params, move Q only in the vector v[i] to
+        //    minimize the function.
+
+        baseFuncVal = func(Q, coords);
+        currFuncVal = baseFuncVal;
+        diff = 0.0;
+        biggestDiff = 0;
+        biggestIter = 0;
+        for (i=0;i<numDims;i++) {
+            if (myParamMask->data.U8[i] == 0) {
+                dummyMin.maxIter = 100;
+                dummyMin.tol = 0.01;
+                mul = p_psLineMin(&dummyMin, Q, v[i], myParamMask, coords, func);
+                if (fabs(dummyMin.value - currFuncVal) > biggestDiff) {
+                    biggestDiff = fabs(dummyMin.value - currFuncVal);
+                    biggestIter = i;
+                }
+                currFuncVal = dummyMin.value;
+            }
+        }
+
+        // 4: Set the vector u = Q - P
+        for (i=0;i<numDims;i++) {
+            if (myParamMask->data.U8[i] == 0) {
+                u->data.F32[i] = Q->data.F32[i] - params->data.F32[i];
+
+                psTrace(".psLib.dataManip.psMinimizePowell", 6,
+                        "u=Q-P (%f = %f - %f)\n", u->data.F32[i],
+                        Q->data.F32[i],
+                        params->data.F32[i]);
+
+            } else {
+                u->data.F32[i] = 0.0;
+            }
+        }
+
+        // 5: Move Q only in the direction u, and minimize the function.
+        psTrace(".psLib.dataManip.psMinimizePowell", 6, "HERE 01\n");
+        for (i=0;i<numDims;i++) {
+            psTrace(".psLib.dataManip.psMinimizePowell", 6,
+                    "u[i] is %f\n", u->data.F32[i]);
+        }
+
+        mul = p_psLineMin(min, params, u, myParamMask, coords, func);
+
+        // 6:
+        if (min->value > currFuncVal) {
+            for (i=0;i<numDims;i++) {
+                psFree(v[i]);
+            }
+            psFree(v);
+            psFree(u);
+            psFree(pQP);
+            psFree(Q);
+            if (paramMask == NULL) {
+                psFree(myParamMask);
+            }
+            psTrace(".psLib.dataManip.psMinimizePowell", 4,
+                    "---- psMinimizePowell() end (true) ----\n");
+            return(true);
+        }
+
+        for (i=0;i<numDims;i++) {
+            if (myParamMask->data.U8[i] == 0) {
+                pQP->data.F32[i] = (2 * Q->data.F32[i]) - params->data.F32[i];
+            } else {
+                pQP->data.F32[i] = params->data.F32[i];
+            }
+        }
+        fqp = func(pQP, coords);
+
+        term1 = (baseFuncVal - currFuncVal) - biggestDiff;
+        term1*= term1;
+        term1*= 2.0 * (baseFuncVal - (2.0 * currFuncVal) + fqp);
+        term2 = baseFuncVal - fqp;
+        term2*= term2 * biggestDiff;
+        if (term1 < term2) {
+            for (i=0;i<numDims;i++) {
+                if (myParamMask->data.U8[i] == 0) {
+                    v[biggestIter]->data.F32[i] = u->data.F32[i];
+                }
+            }
+        }
+
+        // 7: Set P to Q
+        for (i=0;i<numDims;i++) {
+            if (myParamMask->data.U8[i] == 0) {
+                params->data.F32[i] = Q->data.F32[i];
+            }
+        }
+
+        // 8: Go to step 3 until the change is less than some tolerance.
+        if (fabs(baseFuncVal - currFuncVal) <= min->tol) {
+            for (i=0;i<numDims;i++) {
+                psFree(v[i]);
+            }
+            psFree(v);
+            psFree(u);
+            psFree(pQP);
+            psFree(Q);
+            psTrace(".psLib.dataManip.psMinimizePowell", 4,
+                    "---- psMinimizePowell() end (true) ----\n");
+            if (paramMask == NULL) {
+                psFree(myParamMask);
+            }
+            return(true);
+        }
+    }
+
+    if (paramMask == NULL) {
+        psFree(myParamMask);
+    }
+    for (i=0;i<numDims;i++) {
+        psFree(v[i]);
+    }
+    psFree(v);
+    psFree(u);
+    psFree(pQP);
+    psFree(Q);
+    psTrace(".psLib.dataManip.psMinimizePowell", 4,
+            "---- psMinimizePowell() end (false) ----\n");
+    return(false);
+}
+
+/******************************************************************************
+This routine is to be used with the psMinimizeChi2Powell() function below.
+and the psMinimizePowell() function above.
+ 
+The basic idea is calculate chi-squared for a set of params/coords/errors.
+This functions uses global variables to receive the function pointer, the
+data values, and the data errors.
+XXX: This is F32 only
+ *****************************************************************************/
+float myPowellChi2Func(const psVector *params,
+                       const psArray *coords)
+{
+    float chi2 = 0.0;
+    float d;
+    int i;
+    psVector *tmp;
+
+    tmp = Chi2PowellFunc(params, coords);
+    for (i=0;i<coords->n;i++) {
+        d = (tmp->data.F32[i] - myValue->data.F32[i]) / myError->data.F32[i];
+        chi2+= d * d;
+    }
+    psFree(tmp);
+    return(chi2);
+}
+
+
+/******************************************************************************
+This routine must minimize the chi-squared match of a set of data points and
+values for a possibly multi-dimensional function.
+ 
+The basic idea is to use the psMinimizePowell() function defined above.  In
+order to do so, we defined above a function myPowellChi2Func() which takes
+the "func" function and returns chi-squared over the params/coords/values.
+We then use that function myPowellChi2Func() in the call to
+psMinimizePowell().
+ *****************************************************************************/
+bool psMinimizeChi2Powell(psMinimization *min,
+                          psVector *params,
+                          const psVector *paramMask,
+                          const psArray *coords,
+                          const psVector *value,
+                          const psVector *error,
+                          psMinimizeChi2PowellFunc func)
+{
+    myValue = (psVector *) value;
+    myError = (psVector *) error;
+    Chi2PowellFunc = func;
+
+    return(psMinimizePowell(min, params, paramMask, coords, myPowellChi2Func));
+}
+
+
Index: /branches/rel3/psLib/src/dataManip/psMinimize.h
===================================================================
--- /branches/rel3/psLib/src/dataManip/psMinimize.h	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/psMinimize.h	(revision 2163)
@@ -0,0 +1,127 @@
+/** @file  psMinimize.c
+ *  \brief basic minimization functions
+ *  @ingroup Math
+ *
+ *  This file will contain function prototypes for various minimization,
+ *  chi-squared minimization, and 1-D polynomial fitting routines.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.29 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-06 23:38:49 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#if !defined(PS_MINIMIZE_H)
+#define PS_MINIMIZE_H
+
+#include <stdio.h>
+#include <float.h>
+#include <math.h>
+
+#include "psMemory.h"
+#include "psVector.h"
+#include "psArray.h"
+#include "psImage.h"
+#include "psMatrix.h"
+#include "psFunctions.h"
+#include "psStats.h"
+#include "psTrace.h"
+#include "psLogMsg.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psConstants.h"
+
+
+/** \file psMinimize.h
+ *  \brief minimization operations
+ *  \ingroup Stats
+ */
+/** \addtogroup Stats
+ *  \{
+ */
+
+typedef struct
+{
+    int maxIter;                       ///< Convergence limit
+    float tol;                         ///< Error Tolerance
+    float value;                       ///< Value of function at minimum
+    int iter;                          ///< Number of iterations required
+    float lastDelta;                   ///< The last difference for the fit
+}
+psMinimization;
+
+psMinimization *psMinimizationAlloc(int maxIter,
+                                    float tol);
+
+/** Derive a polynomial fit.
+ *
+ *  psVectorFitPolynomial1d returns the polynomial that best fits the 
+ *  observations. The input parameters are a polynomial that specifies the 
+ *  fit order, myPoly, which will be altered and returned with the best-fit 
+ *  coefficients; and the observations, x, y and yErr. The independent 
+ *  variable list, x may be NULL, in which case the vector index is used. 
+ *  The dependent variable error, yErr may be null, in which case the solution 
+ *  is determined in the assumption that all data errors are equal. This 
+ *  function must be valid only for types psF32, psF64.
+ *
+ *  @return psPolynomial1D*    polynomial fit
+ */
+psPolynomial1D* psVectorFitPolynomial1D(
+    psPolynomial1D* myPoly,            ///< Polynomial to fit
+    const psVector* restrict x,        ///< Ordinates (or NULL to just use the indices)
+    const psVector* restrict y,        ///< Coordinates
+    const psVector* restrict yErr      ///< Errors in coordinates, or NULL
+);
+
+psSpline1D *psVectorFitSpline1D(psSpline1D *mySpline,              ///< The spline which will be generated.
+                                const psVector* restrict x,        ///< Ordinates (or NULL to just use the indices)
+                                const psVector* restrict y,        ///< Coordinates
+                                const psVector* restrict yErr      ///< Errors in coordinates, or NULL
+                               );
+
+
+// XXX: What if any of these arguments are NULL?
+typedef
+float (*psMinimizeLMChi2Func)(psVector *deriv,
+                              const psVector *params,
+                              const psVector *coords);
+
+bool psMinimizeLMChi2(psMinimization *min,
+                      psVector *params,
+                      const psVector *paramMask,
+                      psImage *covar,
+                      const psArray *coords,
+                      const psVector *value,
+                      psMinimizeLMChi2Func func);
+
+typedef
+float (*psMinimizePowellFunc)(const psVector *params,
+                              const psArray *coords);
+
+bool psMinimizePowell(psMinimization *min,
+                      psVector *params,
+                      const psVector *paramMask,
+                      const psArray *coords,
+                      psMinimizePowellFunc func);
+
+typedef
+psVector *(*psMinimizeChi2PowellFunc)(const psVector *params,
+                                      const psArray *coords);
+
+bool psMinimizeChi2Powell(psMinimization *min,
+                          psVector *params,
+                          const psVector *paramMask,
+                          const psArray *coords,
+                          const psVector *value,
+                          const psVector *error,
+                          psMinimizeChi2PowellFunc func);
+
+
+
+/* \} */// End of MathGroup Functions
+
+#endif
+
Index: /branches/rel3/psLib/src/dataManip/psStats.c
===================================================================
--- /branches/rel3/psLib/src/dataManip/psStats.c	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/psStats.c	(revision 2163)
@@ -0,0 +1,1908 @@
+/** @file  psStats.c
+ *  \brief basic statistical operations
+ *  @ingroup Stats
+ *
+ *  This file will hold the definition of the histogram and stats data
+ *  structures.  It also contains prototypes for procedures which operate
+ *  on those data structures.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.67 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-13 02:40:13 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <float.h>
+#include <math.h>
+
+/*****************************************************************************/
+/* INCLUDE FILES                                                             */
+/*****************************************************************************/
+#include "psMemory.h"
+#include "psImage.h"
+#include "psVector.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psStats.h"
+#include "psMinimize.h"
+#include "psFunctions.h"
+#include "psConstants.h"
+
+/*****************************************************************************/
+/* DEFINE STATEMENTS                                                         */
+/*****************************************************************************/
+// will use robust statistical methods.
+#define GAUSS_WIDTH 20                     // The width of the Gaussian or boxcar smoothing.
+#define CLIPPED_NUM_ITER_LB 1
+#define CLIPPED_NUM_ITER_UB 10
+#define CLIPPED_SIGMA_LB 1.0
+#define CLIPPED_SIGMA_UB 10.0
+#define true 1
+#define false 0
+#define MY_MAX_FLOAT HUGE
+#define MAX_ITERATIONS 10
+
+void p_psVectorRobustStats(const psVector* restrict myVector,
+                           const psVector* restrict maskVector, unsigned int maskVal, psStats* stats);
+
+
+/*****************************************************************************/
+/* TYPE DEFINITIONS                                                          */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* GLOBAL VARIABLES                                                          */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FILE STATIC VARIABLES                                                     */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - LOCAL                                           */
+/*****************************************************************************/
+
+bool p_psGetStatValue(const psStats* stats, double *value)
+{
+
+    switch (stats->options & ~(PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE | PS_STAT_ROBUST_FOR_SAMPLE)) {
+    case PS_STAT_SAMPLE_MEAN:
+        *value = stats->sampleMean;
+        return true;
+
+    case PS_STAT_SAMPLE_MEDIAN:
+        *value = stats->sampleMedian;
+        return true;
+
+    case PS_STAT_SAMPLE_STDEV:
+        *value = stats->sampleStdev;
+        return true;
+
+    case PS_STAT_ROBUST_MEAN:
+        *value = stats->robustMean;
+        return true;
+
+    case PS_STAT_ROBUST_MEDIAN:
+        *value = stats->robustMedian;
+        return true;
+
+    case PS_STAT_ROBUST_MODE:
+        *value = stats->robustMode;
+        return true;
+
+    case PS_STAT_ROBUST_STDEV:
+        *value = stats->robustStdev;
+        return true;
+
+    case PS_STAT_CLIPPED_MEAN:
+        *value = stats->clippedMean;
+        return true;
+
+    case PS_STAT_CLIPPED_STDEV:
+        *value = stats->clippedStdev;
+        return true;
+
+    case PS_STAT_MAX:
+        *value = stats->max;
+        return true;
+
+    case PS_STAT_MIN:
+        *value = stats->min;
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+/*****************************************************************************
+p_psVectorPrint(myVector, maskVector, maskVal, stats): a private internal
+function that simply prints a vector to STDOUT.  Used primarily for
+debugging.
+ *****************************************************************************/
+
+void p_psVectorPrint(psVector* myVector, psVector* maskVector, unsigned int maskVal, psStats* stats)
+{
+    int i = 0;                  // Loop index variable.
+
+    for (i = 0; i < myVector->n; i++) {
+        if (maskVector != NULL)
+            printf("Element %d is %f (mask is %d)\n", i, myVector->data.F32[i], maskVector->data.U8[i]);
+        else
+            printf("Element %d is %f\n", i, myVector->data.F32[i]);
+    }
+}
+
+/******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+    MISC PRIVATE STATISTICAL FUNCTIONS
+ 
+    NOTE: it is assumed that any call to these statistical functions will
+    have been preceded by a call to the psVectorStats() function.  Various
+    sanity tests will only be performed in psVectorStats().
+        Is the mask vector the same length as the data vector?
+        Is the mask vector of type PS_TYPE_U8?
+        Is the stats data structure NULL?
+        Is the in data structure NULL?
+        Is the in data structure of type PS_TYPE_F32?
+ ******************************************************************************
+ ******************************************************************************
+ *****************************************************************************/
+
+/******************************************************************************
+p_psVectorSampleMean(myVector, maskVector, maskVal, stats): calculates the
+mean of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ASSUMPTION: the mean is always calculated exactly.  Robust means are never
+calculated in this routine.
+ *****************************************************************************/
+
+void p_psVectorSampleMean(const psVector* restrict myVector,
+                          const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    int i = 0;                  // Loop index variable
+    float mean = 0.0;           // The mean
+    int count = 0;              // # of points in this mean?
+    float rangeMin = 0.0;       // Exclude data below this
+    float rangeMax = 0.0;       // Exclude date above this
+
+    // If PS_STAT_USE_RANGE is requested, then we enter a slightly different
+    // loop.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                // Check if the data is with the specified range
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    mean += myVector->data.F32[i];
+                    count++;
+                }
+            }
+            mean /= (float)count;
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    mean += myVector->data.F32[i];
+                    count++;
+                }
+            }
+            mean /= (float)count;
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    mean += myVector->data.F32[i];
+                    count++;
+                }
+            }
+            mean /= (float)count;
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                mean += myVector->data.F32[i];
+            }
+            mean /= (float)myVector->n;
+        }
+    }
+
+    stats->sampleMean = mean;
+}
+
+/******************************************************************************
+p_psVectorSampleMax(myVector, maskVector, maskVal, stats): calculates the
+max of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorMax(const psVector* restrict myVector,
+                   const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    int i = 0;                  // Loop index variable
+    float max = -MY_MAX_FLOAT;  // The calculated maximum
+    float rangeMin = 0.0;       // Exclude data below this
+    float rangeMax = 0.0;       // Exclude date above this
+
+    // If PS_STAT_USE_RANGE is requested, then we enter a different loop.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if ((myVector->data.F32[i] > max) &&
+                            (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                        max = myVector->data.F32[i];
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((myVector->data.F32[i] > max) &&
+                        (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    max = myVector->data.F32[i];
+                }
+            }
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if (myVector->data.F32[i] > max) {
+                        max = myVector->data.F32[i];
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if (myVector->data.F32[i] > max) {
+                    max = myVector->data.F32[i];
+                }
+            }
+        }
+    }
+
+    stats->max = max;
+}
+
+/******************************************************************************
+p_psVectorSampleMin(myVector, maskVector, maskVal, stats): calculates the
+minimum of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorMin(const psVector* restrict myVector,
+                   const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    int i = 0;                  // Loop index variable
+    float min = MY_MAX_FLOAT;   // The calculated maximum
+    float rangeMin = 0.0;       // Exclude data below this
+    float rangeMax = 0.0;       // Exclude date above this
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if ((myVector->data.F32[i] < min) &&
+                            (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                        min = myVector->data.F32[i];
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((myVector->data.F32[i] < min) &&
+                        (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    min = myVector->data.F32[i];
+                }
+            }
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if (myVector->data.F32[i] < min) {
+                        min = myVector->data.F32[i];
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if (myVector->data.F32[i] < min) {
+                    min = myVector->data.F32[i];
+                }
+            }
+        }
+    }
+
+    stats->min = min;
+}
+
+/******************************************************************************
+p_psVectorNValues(myVector, maskVector, maskVal, stats): calculates the
+number of non-masked pixels in the vector that fall within the min/max
+range, if given.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+int p_psVectorNValues(const psVector* restrict myVector,
+                      const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    int i = 0;                  // Loop index variable
+    int numData = 0;            // The number of data points
+    float rangeMin = 0.0;       // Exclude data below this
+    float rangeMax = 0.0;       // Exclude date above this
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    numData++;
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    numData++;
+                }
+            }
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    numData++;
+                }
+            }
+        } else {
+            numData = myVector->n;
+        }
+    }
+    return (numData);
+}
+
+/******************************************************************************
+p_psVectorSampleMedian(myVector, maskVector, maskVal, stats): calculates the
+median of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorSampleMedian(const psVector* restrict myVector,
+                            const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    psVector* unsortedVector = NULL;    // Temporary vector
+    psVector* sortedVector = NULL;      // Temporary vector
+    int i = 0;                  // Loop index variable
+    int count = 0;              // # of points in this mean?
+    int nValues = 0;            // # of points in vector
+    float rangeMin = 0.0;       // Exclude data below this
+    float rangeMax = 0.0;       // Exclude date above this
+
+    // Determine if the number of data points exceed a threshold which will
+    // cause to generate robust stats, as opposed to exact stats.
+    // XXX: This code is no longer used.  We now calculate the median exactly
+    // regardless of the vector size.
+    /*
+     * // Calculate the robust quartiles. stats2 = psStatsAlloc(PS_STAT_ROBUST_MEDIAN);
+     * p_psVectorRobustStats(myVector, maskVector, maskVal, stats2);
+     * 
+     * // Store the robust quartiles into the sample quartile members. stats->sampleMedian =
+     * stats2->robustMedian;
+     * 
+     * // Free temporary data buffers. psFree(stats2);
+     * 
+     * // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure. stats->options = stats->options |
+     * PS_STAT_ROBUST_FOR_SAMPLE;
+     * 
+     * return; } */
+
+    // Determine how many data points fit inside this min/max range
+    // and are not masked, IF the maskVector is not NULL>
+    nValues = p_psVectorNValues(myVector, maskVector, maskVal, stats);
+
+    // Allocate temporary vectors for the data.
+    unsortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
+    unsortedVector->n = unsortedVector->nalloc;
+
+    sortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
+    sortedVector->n = sortedVector->nalloc;
+
+    // Determine if we must only use data points within a min/max range.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+
+        // Store all non-masked data points within the min/max range
+        // into the temporary vectors.
+        count = 0;
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    unsortedVector->data.F32[count++] = maskVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        }
+    } else {
+        // Store all non-masked data points into the temporary vectors.
+        count = 0;
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                unsortedVector->data.F32[i] = myVector->data.F32[i];
+            }
+        }
+    }
+    // Sort the temporary vectors.
+    psVectorSort(sortedVector, unsortedVector);
+
+    // Calculate the median exactly.
+    // XXX: Is this the correct action?
+    if (0 == (nValues % 2)) {
+        stats->sampleMedian = 0.5 * (sortedVector->data.F32[(nValues / 2) - 1] +
+                                     sortedVector->data.F32[nValues / 2]);
+    } else {
+        stats->sampleMedian = sortedVector->data.F32[nValues / 2];
+    }
+
+    // Free the temporary data structures.
+    psFree(unsortedVector);
+    psFree(sortedVector);
+}
+
+/******************************************************************************
+    This routine smoothes the data in the input robustHistogram with a
+    Gaussian of width sigma.
+ 
+    XXX: Must consult with IfA on the proper values for the Gaussian
+    smoothing.  Currently, the Gaussian coefficients are such that only
+    the center coefficient is non-zero.  This is because "e" is being
+    raised to a very large negative number for all points except the
+    center point.
+ 
+    XXX: use a static variable for gaussianCoefs[] and compute them once.
+ *****************************************************************************/
+psVector* p_psVectorsmoothHistGaussian(psHistogram* robustHistogram,
+                                       float sigma)
+{
+    int i = 0;                  // Loop index variable
+    int j = 0;                  // Loop index variable
+    float denom = 0.0;          // Temporary variable
+    float expo = 0.0;           // Temporary variable
+    float gaussianCoefs[1 + (2 * GAUSS_WIDTH)]; // The Gaussian Coefficients
+    psVector* smooth = psVectorAlloc(robustHistogram->nums->n, PS_TYPE_F32);
+
+    for (i = 0; i < (1 + (2 * GAUSS_WIDTH)); i++) {
+        if (fabs(sigma) >= FLT_EPSILON) {
+            // If sigma does not equal zero, then we use Gaussian smoothing.
+            #ifdef  DARWIN
+            denom = (float)sqrt(2.0 * M_PI * sigma * sigma);
+            #else
+
+            denom = sqrtf(2.0 * M_PI * sigma * sigma);
+            #endif
+
+            expo = -(float)((i - GAUSS_WIDTH) * (i - GAUSS_WIDTH));
+            expo /= (2.0 * sigma * sigma);
+            gaussianCoefs[i] = exp(expo / denom);
+
+            //printf("p_psVectorsmoothHistGaussian(): gaussianCoefs[%d] is %f\n", i, gaussianCoefs[i]);
+            // NOTE: Gaussian smoothing just isn't working with low sigma
+            // values.  The problem is that the Gaussian coefficients are
+            // all zero, except for the middle coefficient, which is exactly
+            // one.  Therefore, I'm using boxcar smoothing.
+            gaussianCoefs[i] = 1.0 / (1.0 + (2.0 * (float)GAUSS_WIDTH));
+            // printf("gaussianCoefs[%d] is %f\n", i, gaussianCoefs[i]);
+        } else {
+            /* If sigma equals zero (all pixels have the same value) the above code will divide by zero.
+             * Therefore, we don't need to smooth the data. */
+            for (i = 0; i < robustHistogram->nums->n; i++) {
+                smooth->data.F32[i] = (float)robustHistogram->nums->data.S32[i];
+            }
+            return (smooth);
+        }
+    }
+
+    // Perform the actual smoothing.
+    for (i = 0; i < robustHistogram->nums->n; i++) {
+        smooth->data.F32[i] = 0.0;
+        for (j = -GAUSS_WIDTH; j <= +GAUSS_WIDTH; j++) {
+            if (((j + i) >= 0) && ((j + i) < smooth->n)) {
+                smooth->data.F32[i] += (gaussianCoefs[j + GAUSS_WIDTH] *
+                                        (float)robustHistogram->nums->data.S32[j + i]);
+            }
+        }
+    }
+    return (smooth);
+}
+
+/******************************************************************************
+p_psVectorSampleQuartiles(myVector, maskVector, maskVal, stats): calculates
+the upper and/or lower quartiles of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorSampleQuartiles(const psVector* restrict myVector,
+                               const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    psVector* unsortedVector = NULL;    // Temporary vector
+    psVector* sortedVector = NULL;      // Temporary vector
+    int i = 0;                  // Loop index variable
+    int count = 0;              // # of points in this mean?
+    int nValues = 0;            // # data points
+    float rangeMin = 0.0;       // Exclude data below this
+    float rangeMax = 0.0;       // Exclude date above this
+
+    // Determine how many data points fit inside this min/max range
+    // and are not maxed, IF the maskVector is not NULL>
+    nValues = p_psVectorNValues(myVector, maskVector, maskVal, stats);
+
+    // Allocate temporary vectors for the data.
+    unsortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
+    unsortedVector->n = unsortedVector->nalloc;
+    sortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
+    sortedVector->n = sortedVector->nalloc;
+
+    // Determine if we must only use data points within a min/max range.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        // Store all non-masked data points within the min/max range
+        // into the temporary vectors.
+        count = 0;
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        }
+    } else {
+        // Store all non-masked data points into the temporary vectors.
+        count = 0;
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                unsortedVector->data.F32[i] = myVector->data.F32[i];
+            }
+        }
+    }
+
+    // Sort the temporary vectors.
+    psVectorSort(sortedVector, unsortedVector);
+
+    // Calculate the quartile points exactly.
+    stats->sampleUQ = sortedVector->data.F32[3 * (nValues / 4)];
+    stats->sampleLQ = sortedVector->data.F32[nValues / 4];
+
+    // Free the temporary data structures.
+    psFree(unsortedVector);
+    psFree(sortedVector);
+}
+
+/******************************************************************************
+p_psVectorSampleStdev(myVector, maskVector, maskVal, stats): calculates the
+stdev of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ 
+ *****************************************************************************/
+void p_psVectorSampleStdev(const psVector* restrict myVector,
+                           const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    int i = 0;                  // Loop index variable
+    int countInt = 0;           // # of data points being used
+    float countFloat = 0.0;     // # of data points being used
+    float mean = 0.0;           // The mean
+    float diff = 0.0;           // Used in calculating stdev
+    float sumSquares = 0.0;     // temporary variable
+    float sumDiffs = 0.0;       // temporary variable
+    float rangeMin = 0.0;       // Exclude data below this
+    float rangeMax = 0.0;       // Exclude date above this
+
+    // This procedure requires the mean.  If it has not been already
+    // calculated, then call p_psVectorSampleMean()
+    if (0 != isnan(stats->sampleMean)) {
+        p_psVectorSampleMean(myVector, maskVector, maskVal, stats);
+    }
+    mean = stats->sampleMean;
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares += (diff * diff);
+                    sumDiffs += diff;
+                    countInt++;
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares += (diff * diff);
+                    sumDiffs += diff;
+                    countInt++;
+                }
+            }
+            countInt = myVector->n;
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares += (diff * diff);
+                    sumDiffs += diff;
+                    countInt++;
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                diff = myVector->data.F32[i] - mean;
+                sumSquares += (diff * diff);
+                sumDiffs += diff;
+                countInt++;
+            }
+            countInt = myVector->n;
+        }
+    }
+    countFloat = (float)countInt;
+
+    #ifdef DARWIN
+
+    stats->sampleStdev = (float)sqrt((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
+    #else
+
+    stats->sampleStdev = sqrtf((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
+    #endif
+}
+
+/******************************************************************************
+p_psVectorClippedStats(myVector, maskVector, maskVal, stats): calculates the
+clipped stats (mean or stdev) of the input vector.
+ 
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorClippedStats(const psVector* restrict myVector,
+                            const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    int i = 0;                  // Loop index variable
+    int j = 0;                  // Loop index variable
+    float clippedMean = 0.0;    // self-explanatory
+    float clippedStdev = 0.0;   // self-explanatory
+    float oldStanMean = 0.0;    // Temporary variable
+    float oldStanStdev = 0.0;   // Temporary variable
+    psVector* tmpMask = NULL;   // Temporary vector
+
+    // Endure that stats->clipIter is within the proper range.
+    if (!((CLIPPED_NUM_ITER_LB <= stats->clipIter) && (stats->clipIter <= CLIPPED_NUM_ITER_UB))) {
+        psAbort(__func__, "Unallowed value for clipIter (%d).\n", stats->clipIter);
+    }
+    // Endure that stats->clipSigma is within the proper range.
+    if (!((CLIPPED_SIGMA_LB <= stats->clipSigma) && (stats->clipSigma <= CLIPPED_SIGMA_UB))) {
+        psAbort(__func__, "Unallowed value for clipSigma (%f).\n", stats->clipSigma);
+    }
+    // We allocate a temporary mask vector since during the iterative
+    // steps that follow, we will be masking off additional data points.
+    // However, we do no want to modify the original mask vector.
+    tmpMask = psVectorAlloc(myVector->n, PS_TYPE_U8);
+    tmpMask->n = myVector->n;
+
+    // If we were called with a mask vector, then initialize the temporary
+    // mask vector with those values.
+    if (maskVector != NULL) {
+        for (i = 0; i < tmpMask->n; i++) {
+            tmpMask->data.U8[i] = maskVector->data.U8[i];
+        }
+    }
+    // 1. Compute the sample median.
+    // NOTE: This seems odd.  Verify with IfA that we want to calculate the
+    // median here, not the mean.
+    p_psVectorSampleMedian(myVector, maskVector, maskVal, stats);
+
+    // 2. Compute the sample standard deviation.
+    p_psVectorSampleStdev(myVector, maskVector, maskVal, stats);
+
+    // 3. Use the sample median as the first estimator of the mean X.
+    clippedMean = stats->sampleMean;
+
+    // 4. Use the sample stdev as the first estimator of the mean stdev.
+    clippedStdev = stats->sampleStdev;
+
+    // Must save the old sampleMean and sampleStdev since the following code
+    // block overwrites them.
+    oldStanMean = stats->sampleMean;
+    oldStanStdev = stats->sampleStdev;
+
+    // 5. Repeat N times:
+    for (i = 0; i < stats->clipIter; i++) {
+        for (j = 0; j < myVector->n; j++) {
+            // a) Exclude all values x_i for which |x_i - x| > K * stdev
+            if (fabs(myVector->data.F32[j] - clippedMean) > (stats->clipSigma * clippedStdev)) {
+                tmpMask->data.U8[i] = 0xff;
+            }
+            // b) compute new mean and stdev
+            p_psVectorSampleMedian(myVector, tmpMask, maskVal, stats);
+            p_psVectorSampleStdev(myVector, tmpMask, maskVal, stats);
+
+            // c) Use the new mean for x
+            clippedMean = stats->sampleMean;
+
+            // d) Use the new stdev for stdev
+            clippedStdev = stats->sampleStdev;
+        }
+
+    }
+    stats->sampleMean = oldStanMean;
+    stats->sampleStdev = oldStanStdev;
+
+    // 7. The last calcuated value of x is the cliped mean.
+    if (stats->options & PS_STAT_CLIPPED_MEAN) {
+        stats->clippedMean = clippedMean;
+    }
+    // 8. The last calcuated value of stdev is the cliped stdev.
+    if (stats->options & PS_STAT_CLIPPED_STDEV) {
+        stats->clippedStdev = clippedStdev;
+    }
+
+    psFree(tmpMask);
+}
+
+/*****************************************************************************
+p_psNormalizeVectorF32(myData): this is a private function which normalizes the
+elements of a vector to a range between 0.0 and 1.0.
+ *****************************************************************************/
+void p_psNormalizeVectorF32(psVector* myData)
+{
+    float min = (float)HUGE;
+    float max = (float)-HUGE;
+    int i = 0;
+
+    for (i = 0; i < myData->n; i++) {
+        if (myData->data.F32[i] < min) {
+            min = myData->data.F32[i];
+        }
+        if (myData->data.F32[i] > max) {
+            max = myData->data.F32[i];
+        }
+    }
+
+    //  float range = max - min;
+    //    for (i = 0; i < myData->n; i++) {
+    //        myData->data.F32[i] = (myData->data.F32[i] - min) / range;
+    //    }
+    for (i = 0; i < myData->n; i++) {
+        myData->data.F32[i] = (myData->data.F32[i] - 0.5 * (min + max)) /
+                              (0.5 * (max - min));
+    }
+}
+
+/*****************************************************************************
+p_psNormalizeVectorF64(myData): this is a private function which normalizes the
+elements of a vector to a range between -1.0 and 1.0.
+XXX: 0-1 or -1:1?
+ *****************************************************************************/
+void p_psNormalizeVectorF64(psVector* myData)
+{
+    float min = (double)HUGE;
+    float max = (double)-HUGE;
+    double range = 0.0;
+    int i = 0;
+
+    for (i = 0; i < myData->n; i++) {
+        if (myData->data.F64[i] < min) {
+            min = myData->data.F64[i];
+        }
+        if (myData->data.F64[i] > max) {
+            max = myData->data.F64[i];
+        }
+    }
+
+    range = max - min;
+    for (i = 0; i < myData->n; i++) {
+        myData->data.F64[i] = -1.0 + 2.0 *
+                              ((myData->data.F64[i] - min) / range);
+    }
+
+    //    for (i = 0; i < myData->n; i++) {
+    //        myData->data.F64[i] = (myData->data.F64[i] - 0.5 * (min + max)) /
+    //                              (0.5 * (max - min));
+    //    }
+}
+
+void p_psNormalizeVector(psVector* myData)
+{
+    if (myData->type.type == PS_TYPE_F32) {
+        p_psNormalizeVectorF32(myData);
+    } else if (myData->type.type == PS_TYPE_F64) {
+        p_psNormalizeVectorF64(myData);
+    } else {
+        psError(__func__, "Unalowable data type.\n");
+    }
+}
+
+/*****************************************************************************
+p_psGaussian(myData, myParams): an internal function, used by robust stats,
+intended to compute the Gaussian with a specified sigma/mean, at the
+specified data point.
+ *****************************************************************************/
+float p_psGaussian(const psVector* restrict myData, const psVector* restrict myParams)
+{
+    float x = myData->data.F32[0];
+    float mean = myParams->data.F32[0];
+    float stdev = myParams->data.F32[1];
+    float tmp = exp(-((x - mean) * (x - mean)) / (2.0 * stdev * stdev));
+
+    tmp /= ((float)sqrt(2.0 * M_PI * (stdev * stdev)));
+
+    // printf("p_psGaussian((%.2f), %.2f, %.2f) is %.2f\n", x, mean, stdev, tmp);
+    return (tmp);
+}
+
+/*****************************************************************************
+p_psGaussianDeriv(myData, myParams, whichParam): an internal function, which
+calculates the specified partial derivative of the above Gaussian function.
+ *****************************************************************************/
+float p_psGaussianDeriv(const psVector* restrict myData, const psVector* restrict myParams, int whichParam)
+{
+    float x = myData->data.F32[0];
+    float mean = myParams->data.F32[0];
+    float stdev = myParams->data.F32[1];
+    float tmp = 0.0;
+
+    if (whichParam == 0) {
+        // Return the derivative w.r.t. the mean.
+        tmp = (x - mean) * p_psGaussian(myData, myParams);
+        tmp /= (stdev * stdev);
+    } else if (whichParam == 1) {
+        // Return the derivative w.r.t. the stdev.
+        tmp = (x - mean) * (x - mean) * p_psGaussian(myData, myParams);
+        tmp /= (stdev * stdev * stdev);
+    }
+    printf("p_psGaussianDeriv((%.2f), %.2f, %.2f, (%d)) is %.2f\n", x, mean, stdev, whichParam, tmp);
+
+    return (tmp);
+}
+
+/*****************************************************************************
+p_psQuadratic(myData, myParams): an internal function, used by robust stats,
+intended to compute a quadratic, with the specified parameters, at the
+specified data point.
+ *****************************************************************************/
+float p_psQuadratic(const psVector* restrict myParams, const psVector* restrict myCoords)
+{
+    float x = myCoords->data.F32[0];
+    float A = myParams->data.F32[0];
+    float B = myParams->data.F32[1];
+    float C = myParams->data.F32[2];
+    float tmp = 0.0;
+
+    tmp = (A * x * x) + (B * x) + C;
+    return (tmp);
+}
+
+/*****************************************************************************
+p_psQuadraticDeriv(myData, myParams, whichParam): an internal function, which
+calculates the specified partial derivative of the above quadratic function.
+ *****************************************************************************/
+float p_psQuadraticDeriv(const psVector* restrict myParams,
+                         const psVector* restrict myCoords, int whichParamDeriv)
+{
+    float x = myCoords->data.F32[0];
+    float tmp = 0.0;
+
+    if (whichParamDeriv == 0) {
+        tmp = x * x;
+    } else if (whichParamDeriv == 1) {
+        tmp = x;
+    } else if (whichParamDeriv == 2) {
+        tmp = 1.0;
+    }
+
+    return (tmp);
+}
+
+/******************************************************************************
+p_ps1DPolyMedian(myPoly, rangeLow, rangeHigh, midpoint): This routine takes
+as input a 1-D polynomial of arbitrary order (though we are using 2nd-order
+polynomials here) and a range of x-values for which it is defined:
+[rangeLow, rangeHigh].  It determines the x-value of that polynomial such
+that f(x) == midpoint.  This functions uses a binary-search algorithm on the
+range and assumes that the polynomial is monotonically increasing or
+decreasing within that range.
+ 
+XXX: Terminate when f(x)-getThisValue is within some error tolerance.
+ *****************************************************************************/
+float p_ps1DPolyMedian(psPolynomial1D* myPoly,
+                       float rangeLow,
+                       float rangeHigh,
+                       float getThisValue)
+{
+    int numIterations = 0;
+    float midpoint = 0.0;
+    float oldMidpoint = 1.0;
+    float f = 0.0;
+
+    // printf("p_ps1DPolyMedian(%f, %f, %f) \n", rangeLow, rangeHigh, getThisValue);
+
+    while (numIterations < MAX_ITERATIONS) {
+        midpoint = (rangeHigh + rangeLow) / 2.0;
+        if (fabs(midpoint - oldMidpoint) <= FLT_EPSILON) {
+            return (midpoint);
+        }
+        oldMidpoint = midpoint;
+
+        f = psPolynomial1DEval(midpoint, myPoly);
+        // printf("p_ps1DPolyMedian() iteration %d.  f(%f) is %f\n", numIterations, midpoint, f);
+        if (fabs(f - getThisValue) <= FLT_EPSILON) {
+            return (midpoint);
+        }
+
+        if (f > getThisValue) {
+            rangeHigh = midpoint;
+        } else {
+            rangeLow = midpoint;
+        }
+        numIterations++;
+    }
+    return (midpoint);
+}
+
+/******************************************************************************
+p_psFitQuadratic(robustHistogram. cumulativeSums, binNum, fitFloat): given
+the specified histogram, with the specified pre-calculated cumulativeSums,
+this routine fits a quadratic f(x) to the 3 bins surrounding bin "binNum",
+and then finds the point x such that f(x) == fitFloat.
+ 
+XXX: This function is currently not being used.
+ *****************************************************************************/
+float p_psFitQuadratic(psHistogram* histogram,
+                       psVector* cumulativeSums,
+                       int binNum,
+                       float fitFloat)
+{
+    psVector* x = psVectorAlloc(3, PS_TYPE_F64);
+    psVector* y = psVectorAlloc(3, PS_TYPE_F64);
+    psVector* yErr = psVectorAlloc(3, PS_TYPE_F64);
+    psPolynomial1D* myPoly = psPolynomial1DAlloc(2, PS_POLYNOMIAL_ORD);
+
+    if ((binNum > 0) && (binNum < (histogram->nums->n + 1))) {
+        x->data.F64[0] = (double)0.5 *
+                         (histogram->bounds->data.F32[binNum - 1] + histogram->bounds->data.F32[binNum]);
+        x->data.F64[1] = (double)0.5 *
+                         (histogram->bounds->data.F32[binNum] + histogram->bounds->data.F32[binNum + 1]);
+        x->data.F64[2] = (double)0.5 *
+                         (histogram->bounds->data.F32[binNum + 1] + histogram->bounds->data.F32[binNum + 2]);
+
+        y->data.F64[0] = cumulativeSums->data.F32[binNum - 1];
+        y->data.F64[1] = cumulativeSums->data.F32[binNum];
+        y->data.F64[2] = cumulativeSums->data.F32[binNum + 1];
+
+        if (!((y->data.F64[0] <= fitFloat) && (fitFloat <= y->data.F64[2]))) {
+            psAbort(__func__, "p_psVectorRobustStats(0): midpoint not within y-range\n");
+        }
+
+        yErr->data.F64[0] = 1.0;
+        yErr->data.F64[1] = 1.0;
+        yErr->data.F64[2] = 1.0;
+
+        myPoly = psVectorFitPolynomial1D(myPoly, x, y, yErr);
+        return (p_ps1DPolyMedian(myPoly, x->data.F64[0], x->data.F64[2], fitFloat));
+    } else {
+        return (0.5 * (histogram->bounds->data.F32[binNum + 1] + histogram->bounds->data.F32[binNum]));
+    }
+
+    psFree(x);
+    psFree(y);
+    psFree(yErr);
+    psFree(myPoly);
+    return (0.0);
+}
+
+/******************************************************************************
+p_psVectorRobustStats(myVector, maskVector, maskVal, stats): this procedure
+calculates a variety of robust stat measures:
+    PS_STAT_ROBUST_MEAN
+    PS_STAT_ROBUST_MEDIAN
+    PS_STAT_ROBUST_MODE
+    PS_STAT_ROBUST_STDEV
+    PS_STAT_ROBUST_QUARTILE
+I have included all that computation in a single function, as opposed to
+breaking it across several functions for one primary reason:  they all
+require the same basic initial processing steps (calculate the histogram,
+etc.)  however there is no currently defined means, in the SDRS, to specify
+this computation as a separate step.  If the above robust stat measures were
+calcualted in separate functiosn, then much of the initial processing would
+be duplicated.
+ 
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+*****************************************************************************/
+void p_psVectorRobustStats(const psVector* restrict myVector,
+                           const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    psHistogram* robustHistogram = NULL;
+    psVector* robustHistogramVector = NULL;
+    float binSize = 0.0;        // Size of the histogram bins
+    int LQBinNum = -1;          // Bin num for lower quartile
+    int UQBinNum = -1;          // Bin num for upper quartile
+    int i = 0;                  // Loop index variable
+    int maxBinNum = 0;
+    float maxBinCount = 0.0;
+    float dL = 0.0;
+    int numBins = 0;
+    psStats* tmpStats = psStatsAlloc(PS_STAT_CLIPPED_STDEV | PS_STAT_CLIPPED_MEAN);
+
+    // psImage* domain;
+    // psVector* errors;
+    // psVector* data;
+    // psVector* initialGuess;
+    // psVector* theParams;
+    // float chiSq=0.0;
+    // float max = -HUGE;
+    // float max_pos;
+    float myMean = 0.0;
+    float myStdev = 0.0;
+    float countFloat = 0.0;
+    float diff = 0.0;
+    float sumSquares = 0.0;
+    float sumDiffs = 0.0;
+    psVector* x = psVectorAlloc(3, PS_TYPE_F64);
+    psVector* y = psVectorAlloc(3, PS_TYPE_F64);
+    psVector* yErr = psVectorAlloc(3, PS_TYPE_F64);
+    psPolynomial1D* myPoly = psPolynomial1DAlloc(2, PS_POLYNOMIAL_ORD);
+    psVector* cumulativeRobustSumsFullRange = NULL;
+    psVector* cumulativeRobustSumsDlRange = NULL;
+    float sumRobust = 0.0;
+    float sumN50 = 0.0;
+    float sumNfit = 0.0;
+    float cumulativeMedian = 0.0;
+
+    // Compute the initial bin size of the robust histogram.  This is done
+    // by computing the clipped standard deviation of the vector, and dividing
+    // that by 10.0;
+    p_psVectorClippedStats(myVector, maskVector, maskVal, tmpStats);
+    binSize = tmpStats->clippedStdev / 10.0f;
+
+    // If stats->clippedStdev == 0.0, then all data elements have the same
+    // value.  Therefore, we can set the appropiate results and return.
+    if (fabs(binSize) <= FLT_EPSILON) {
+        if (stats->options & PS_STAT_ROBUST_MEAN) {
+            stats->robustMean = stats->clippedMean;
+        }
+        if (stats->options & PS_STAT_ROBUST_MEDIAN) {
+            stats->robustMedian = stats->clippedMean;
+        }
+        if (stats->options & PS_STAT_ROBUST_MODE) {
+            stats->robustMode = stats->clippedMean;
+        }
+        if (stats->options & PS_STAT_ROBUST_STDEV) {
+            stats->robustStdev = 0.0;
+        }
+        if (stats->options & PS_STAT_ROBUST_QUARTILE) {
+            stats->robustUQ = stats->clippedMean;
+            stats->robustLQ = stats->clippedMean;
+        }
+        // XXX: Set these to the number of unmasked data points?
+        stats->robustNfit = 0.0;
+        stats->robustN50 = 0.0;
+        psFree(tmpStats);
+        return;
+    }
+    // Determine minimum and maximum values in the data vector.
+    if (isnan(stats->min)) {
+        p_psVectorMin(myVector, maskVector, maskVal, stats);
+    }
+    if (isnan(stats->max)) {
+        p_psVectorMax(myVector, maskVector, maskVal, stats);
+    }
+    // Create the histogram structure.  NOTE: we can not specify the bin size
+    // precisely since the argument to psHistogramAlloc() is the number of
+    // bins, not the binSize.  Also, if we get here, we know that
+    // binSize != 0.0.
+    numBins = (int)((stats->max - stats->min) / binSize);
+    robustHistogram = psHistogramAlloc(stats->min, stats->max, numBins);
+
+    // Populate the histogram array.
+    psVectorHistogram(robustHistogram, myVector, maskVector, maskVal);
+
+    // Smooth the histogram.
+    // XXX: is that the right stdev?
+    robustHistogramVector = p_psVectorsmoothHistGaussian(robustHistogram,
+                            tmpStats->clippedStdev / 4.0f);
+
+    // The following was necessary to fit a gaussian to the data, since
+    // gaussian functions produce data between 0.0 and 1.0.
+    // p_psNormalizeVectorF32(robustHistogramVector);
+
+    /**************************************************************************
+    Determine the lower/upper quartiles.
+    **************************************************************************/
+    // We define a vector called "cumulativeRobustSums..." where the value at
+    // index position i is equal to the sum of bins 0:i.  This will be used
+    // now and later in determining the lower/upper quartiles.
+    cumulativeRobustSumsFullRange = psVectorAlloc(robustHistogramVector->n, PS_TYPE_F32);
+    cumulativeRobustSumsFullRange->data.F32[0] = robustHistogramVector->data.F32[0];
+    for (i = 1; i < robustHistogramVector->n; i++) {
+        cumulativeRobustSumsFullRange->data.F32[i] =
+            cumulativeRobustSumsFullRange->data.F32[i - 1] + robustHistogramVector->data.F32[i];
+    }
+    sumRobust = cumulativeRobustSumsFullRange->data.F32[robustHistogramVector->n - 1];
+
+    // Determine the bin number containing the lower quartile point.
+    LQBinNum = -1;
+    for (i = 0; i < cumulativeRobustSumsFullRange->n; i++) {
+        if (cumulativeRobustSumsFullRange->data.F32[i] >= (sumRobust / 4.0)) {
+            LQBinNum = i;
+            break;
+        }
+    }
+
+    // Determine the bin number containing the upper quartile point.
+    UQBinNum = -1;
+    for (i = cumulativeRobustSumsFullRange->n - 1; i >= 0; i--) {
+        if (cumulativeRobustSumsFullRange->data.F32[i] <= (3.0 * sumRobust / 4.0)) {
+            UQBinNum = i;
+            break;
+        }
+    }
+
+    if ((LQBinNum == -1) || (UQBinNum == -1)) {
+        psAbort(__func__, "Could not determine the robust lower/upper quartiles.");
+    }
+
+    /**************************************************************************
+    Determine the mode in the range LQ:UQ.
+    **************************************************************************/
+    // Determine the bin with the peak value in the range LQ to UQ.
+    maxBinNum = LQBinNum;
+    maxBinCount = robustHistogramVector->data.F32[LQBinNum];
+    sumN50 = (float)robustHistogram->nums->data.S32[LQBinNum];
+    for (i = LQBinNum + 1; i <= UQBinNum; i++) {
+        if (robustHistogramVector->data.F32[i] > maxBinCount) {
+            maxBinNum = i;
+            maxBinCount = robustHistogramVector->data.F32[i];
+        }
+        sumN50 += (float)robustHistogram->nums->data.S32[i];
+    }
+
+    // XXX: is dL defined as the value at the LQ/UQ, or the bin number?
+    dL = (UQBinNum - LQBinNum) / 4;
+
+    printf("(LQBinNum, UQBinNum, maxBinNum) is (%d, %d, %d)\n", LQBinNum, UQBinNum, maxBinNum);
+
+    /**************************************************************************
+    Determine the mean/stdev for the bins in the range mode-dL to mode+dL
+    **************************************************************************/
+    cumulativeRobustSumsDlRange = psVectorAlloc(robustHistogramVector->n, PS_TYPE_F32);
+    for (i = 0; i < robustHistogramVector->n; i++) {
+        cumulativeRobustSumsDlRange->data.F32[i] = 0.0;
+    }
+    sumNfit = 0.0;
+    cumulativeMedian = 0.0;
+    for (i = maxBinNum - dL; i <= maxBinNum + dL; i++) {
+        if ((0 <= i) && (i < robustHistogramVector->n)) {
+            cumulativeRobustSumsDlRange->data.F32[i] =
+                cumulativeRobustSumsDlRange->data.F32[i - 1] + robustHistogramVector->data.F32[i];
+            cumulativeMedian += robustHistogramVector->data.F32[i];
+            sumNfit += (float)robustHistogram->nums->data.S32[i];
+        }
+    }
+
+    // Calculate the mean of the smoothed robust histogram in the range
+    // mode-dL to mode+dL.  We use the midpoint of each bin as the mean for
+    // that bin (this is a non-exact approximation).
+    myMean = 0.0;
+    for (i = maxBinNum - dL; i <= maxBinNum + dL; i++) {
+        if ((0 <= i) && (i < robustHistogramVector->n)) {
+            myMean += (robustHistogramVector->data.F32[i]) * 0.5 *
+                      (robustHistogram->bounds->data.F32[i + 1] + robustHistogram->bounds->data.F32[i]);
+            countFloat += robustHistogramVector->data.F32[i];
+        }
+    }
+    myMean /= countFloat;
+
+    // Calculate the stdev of the smoothed robust histogram in the range
+    // mode-dL to mode+dL.  We use the midpoint of each bin as the mean for
+    // that bin.
+    for (i = maxBinNum - dL; i <= maxBinNum + dL; i++) {
+        if ((0 <= i) && (i < robustHistogramVector->n)) {
+            diff = (0.5 * (robustHistogram->bounds->data.F32[i + 1] +
+                           robustHistogram->bounds->data.F32[i])) - myMean;
+            sumSquares += diff * diff * robustHistogramVector->data.F32[i];
+            sumDiffs += diff * robustHistogramVector->data.F32[i];
+        }
+    }
+    myStdev = sqrt((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
+
+    /**************************************************************************
+    Set the appropriate members in the output stats struct.
+    **************************************************************************/
+    if (stats->options & PS_STAT_ROBUST_MEAN) {
+        stats->robustMean = myMean;
+    }
+
+    if (stats->options & PS_STAT_ROBUST_MODE) {
+        stats->robustMode = 0.5 *
+                            (robustHistogram->bounds->data.F32[maxBinNum] + robustHistogram->bounds->data.F32[maxBinNum + 1]);
+    }
+
+    if (stats->options & PS_STAT_ROBUST_STDEV) {
+        stats->robustStdev = myStdev;
+    }
+    // To determine the median (and later, the lower/upper quartile), we fit
+    // a quadratic to the three bins surrounding the bin containing the median.
+    // The quadratic y=f(x) with x being the midpoint of each bin, and y being
+    // the cumulative number of data points in all bins up to, and including,
+    // this bin.  We then solve the quadratic for
+
+    // XXX: Create a "p_psQuadraticFitAndSolveForX() function.
+
+    if (stats->options & PS_STAT_ROBUST_MEDIAN) {
+        if ((maxBinNum > 0) && (maxBinNum < (robustHistogram->nums->n - 1))) {
+            x->data.F64[0] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[maxBinNum - 1] +
+                              robustHistogram->bounds->data.F32[maxBinNum]);
+            x->data.F64[1] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[maxBinNum] +
+                              robustHistogram->bounds->data.F32[maxBinNum + 1]);
+            x->data.F64[2] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[maxBinNum + 1] +
+                              robustHistogram->bounds->data.F32[maxBinNum + 2]);
+
+            y->data.F64[0] = cumulativeRobustSumsDlRange->data.F32[maxBinNum - 1];
+            y->data.F64[1] = cumulativeRobustSumsDlRange->data.F32[maxBinNum];
+            y->data.F64[2] = cumulativeRobustSumsDlRange->data.F32[maxBinNum + 1];
+
+            // Ensure that cumulativeMedian/2 is actually within the range of the bins
+            // we are using.
+            cumulativeMedian *= 0.5;
+            if (!((y->data.F64[0] <= cumulativeMedian) && (cumulativeMedian <= y->data.F64[2]))) {
+                printf("((%f), %f, %f)\n", cumulativeMedian, y->data.F64[0], y->data.F64[2]);
+                psAbort(__func__, "p_psVectorRobustStats(1): midpoint not within y-range\n");
+            }
+            // XXX: yErr is not currently used by psVectorFitPolynomial1D().  We
+            // may have to set this meaningfully later.
+            yErr->data.F64[0] = 1.0;
+            yErr->data.F64[1] = 1.0;
+            yErr->data.F64[2] = 1.0;
+
+            // Determine the coefficients of the polynomial.
+            myPoly = psVectorFitPolynomial1D(myPoly, x, y, yErr);
+            // Call p_ps1DPolyMedian(), which does a binary search on the
+            // polynomial, looking for the value x such that
+            // f(x) = cumulativeMedian.
+            stats->robustMedian = p_ps1DPolyMedian(myPoly, x->data.F64[0], x->data.F64[2], cumulativeMedian);
+        } else {
+            // If the mode is the first/last histogram bin, then simply use
+            // the midpoint of that bin.
+            stats->robustMedian = 0.5 * (robustHistogram->bounds->data.F32[maxBinNum + 1] +
+                                         robustHistogram->bounds->data.F32[maxBinNum]);
+        }
+    }
+    // The lower/upper quartile calculations are very similar to the median
+    // calculations.  We fit a quadratic to the array containing the
+    // cumulative data points in each bin, then search for x such that
+    // f(x) equals the lower/upper quartile exactly.
+    //
+    if (stats->options & PS_STAT_ROBUST_QUARTILE) {
+        countFloat = cumulativeRobustSumsFullRange->data.F32[robustHistogramVector->n - 1];
+
+        if ((LQBinNum > 0) && (LQBinNum < (robustHistogram->nums->n - 1))) {
+            x->data.F64[0] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[LQBinNum - 1] +
+                              robustHistogram->bounds->data.F32[LQBinNum]);
+            x->data.F64[1] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[LQBinNum] +
+                              robustHistogram->bounds->data.F32[LQBinNum + 1]);
+            x->data.F64[2] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[LQBinNum + 1] +
+                              robustHistogram->bounds->data.F32[LQBinNum + 2]);
+
+            y->data.F64[0] = cumulativeRobustSumsFullRange->data.F32[LQBinNum - 1];
+            y->data.F64[1] = cumulativeRobustSumsFullRange->data.F32[LQBinNum];
+            y->data.F64[2] = cumulativeRobustSumsFullRange->data.F32[LQBinNum + 1];
+
+            if (!((y->data.F64[0] <= (countFloat / 4.0)) && ((countFloat / 4.0) <= y->data.F64[2]))) {
+                psAbort(__func__, "p_psVectorRobustStats(2): midpoint not within y-range\n");
+            }
+
+            yErr->data.F64[0] = 1.0;
+            yErr->data.F64[1] = 1.0;
+            yErr->data.F64[2] = 1.0;
+
+            myPoly = psVectorFitPolynomial1D(myPoly, x, y, yErr);
+            stats->robustLQ = p_ps1DPolyMedian(myPoly, x->data.F64[0], x->data.F64[2], countFloat / 4.0);
+
+        } else {
+            // If the LQ is the first/last histogram bin, then simply use
+            // the midpoint of that bin.
+            stats->robustLQ = 0.5 * (robustHistogram->bounds->data.F32[LQBinNum + 1] +
+                                     robustHistogram->bounds->data.F32[LQBinNum]);
+        }
+
+        if ((UQBinNum > 0) && (UQBinNum < (robustHistogram->nums->n - 1))) {
+            x->data.F64[0] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[UQBinNum - 1] +
+                              robustHistogram->bounds->data.F32[UQBinNum]);
+            x->data.F64[1] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[UQBinNum] +
+                              robustHistogram->bounds->data.F32[UQBinNum + 1]);
+            x->data.F64[2] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[UQBinNum + 1] +
+                              robustHistogram->bounds->data.F32[UQBinNum + 2]);
+
+            y->data.F64[0] = cumulativeRobustSumsFullRange->data.F32[UQBinNum - 1];
+            y->data.F64[1] = cumulativeRobustSumsFullRange->data.F32[UQBinNum];
+            y->data.F64[2] = cumulativeRobustSumsFullRange->data.F32[UQBinNum + 1];
+
+            if (!((y->data.F64[0] <= (3.0 * countFloat / 4.0)) &&
+                    ((3.0 * countFloat / 4.0) <= y->data.F64[2]))) {
+                psAbort(__func__, "p_psVectorRobustStats(3): midpoint not within y-range\n");
+            }
+
+            yErr->data.F64[0] = 1.0;
+            yErr->data.F64[1] = 1.0;
+            yErr->data.F64[2] = 1.0;
+
+            myPoly = psVectorFitPolynomial1D(myPoly, x, y, yErr);
+            stats->robustUQ = p_ps1DPolyMedian(myPoly,
+                                               x->data.F64[0], x->data.F64[2], 3.0 * countFloat / 4.0);
+        } else {
+            // If the UQ is the first/last histogram bin, then simply use
+            // the midpoint of that bin.
+            stats->robustUQ = 0.5 * (robustHistogram->bounds->data.F32[UQBinNum + 1] +
+                                     robustHistogram->bounds->data.F32[UQBinNum]);
+        }
+    }
+    stats->robustNfit = sumNfit;
+    stats->robustN50 = sumN50;
+
+    psFree(x);
+    psFree(y);
+    psFree(yErr);
+    psFree(tmpStats);
+    psFree(robustHistogram);
+    psFree(myPoly);
+    psFree(cumulativeRobustSumsFullRange);
+    psFree(cumulativeRobustSumsDlRange);
+}
+
+/*
+void p_ps_FitTheGaussian()
+{
+    // Fit a Gaussian to the bins in the range MODE-dL to Mode+dL
+    // NOTE: This code uses the psMinimize.c functions to perform
+    // the fit.  It doesn't quite work, 100% of the time.  For the time being
+    // I am commenting this code out, and replacing it with code which
+    // calculates the mean directly on the robustHistogram.
+    //
+    // XXX: Replace this with the LaGrange interpolation stuff.
+ 
+    domain = psImageAlloc(1, robustHistogramVector->n, PS_TYPE_F32);
+    errors = psVectorAlloc(robustHistogramVector->n, PS_TYPE_F32);
+    data = psVectorAlloc(robustHistogramVector->n, PS_TYPE_F32);
+    initialGuess = psVectorAlloc(2, PS_TYPE_F32);
+ 
+    max = -HUGE;
+    max_pos = -1;
+    for (i=0;i<robustHistogramVector->n;i++) {
+        domain->data.F32[i][0] = 0.5 * (robustHistogram->bounds->data.F32[i+1] +
+                                        robustHistogram->bounds->data.F32[i]);
+        data->data.F32[i] = (float) robustHistogramVector->data.F32[i];
+        errors->data.F32[i] = 1.0;
+        //printf("DATA (%.2f, %.2f)\n", domain->data.F32[i][0], data->data.F32[i]);
+        if (data->data.F32[i] > max) {
+            max = data->data.F32[i];
+            max_pos = domain->data.F32[i][0];
+        }
+    }
+ 
+    initialGuess->data.F32[0] = max_pos;
+    initialGuess->data.F32[1] = 1.0;
+    printf("Initial (mean. stdev) is (%.3f, %.3f)\n", initialGuess->data.F32[0], initialGuess->data.F32[1]);
+ 
+    printf("Calling psMinimizeChi2()\n");
+    theParams = psMinimizeChi2(p_psGaussian,
+                               p_psGaussianDeriv,
+                               domain,
+                               data,
+                               errors,
+                               initialGuess,
+                               NULL,
+                               &chiSq);
+    printf("Called psMinimizeChi2()\n");
+    printf("p_psVectorRobustStats() is (%f, %f)\n", theParams->data.F32[0], theParams->data.F32[1]);
+}
+*/
+
+/*****************************************************************************/
+
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+
+/*****************************************************************************/
+
+static void histogramFree(psHistogram* myHist);
+
+/******************************************************************************
+    psStatsAlloc(): This routine must create a new psStats data structure.
+ *****************************************************************************/
+psStats* psStatsAlloc(psStatsOptions options)
+{
+    psStats* newStruct = NULL;
+
+    newStruct = (psStats* ) psAlloc(sizeof(psStats));
+    newStruct->sampleMean = NAN;
+    newStruct->sampleMedian = NAN;
+    newStruct->sampleStdev = NAN;
+    newStruct->sampleUQ = NAN;
+    newStruct->sampleLQ = NAN;
+    newStruct->robustMean = NAN;
+    newStruct->robustMedian = NAN;
+    newStruct->robustMode = NAN;
+    newStruct->robustStdev = NAN;
+    newStruct->robustUQ = NAN;
+    newStruct->robustLQ = NAN;
+    newStruct->robustN50 = 0;
+    newStruct->robustNfit = 0;
+    newStruct->clippedMean = NAN;
+    newStruct->clippedStdev = NAN;
+    newStruct->clipSigma = 3.0;
+    newStruct->clipIter = 3.0;
+    newStruct->min = NAN;
+    newStruct->max = NAN;
+    newStruct->binsize = NAN;
+    newStruct->options = options;
+
+    return (newStruct);
+}
+
+/******************************************************************************
+psHistogramAlloc(lower, upper, n): allocate a uniform histogram structure
+with the specifed upper and lower limits, and the specifed number of bins.
+This routine will also set the bounds for each of the bins.
+ 
+Input:
+    lower
+    upper
+    n
+Returns:
+    The histogram structure
+ *****************************************************************************/
+psHistogram* psHistogramAlloc(float lower, float upper, int n)
+{
+    int i = 0;                  // Loop index variable
+    psHistogram* newHist = NULL;        // The new histogram structure
+    float binSize = 0.0;        // The histogram bin size
+
+    // NOTE: Verify that this is the correct action.
+    if (n == 0) {
+        return (NULL);
+    }
+    if (n < 0) {
+        psAbort(__func__, "psHistogramAlloc() called with bin size %d.\n", n);
+    }
+    // NOTE: Verify that this is the correct action.
+    if (lower > upper) {
+        return (NULL);
+    }
+    // Allocate memory for the new histogram structure.  If there are N
+    // bins, then there are N+1 bounds to those bins.
+    newHist = (psHistogram* ) psAlloc(sizeof(psHistogram));
+    p_psMemSetDeallocator(newHist, (psFreeFcn) histogramFree);
+    newHist->bounds = psVectorAlloc(n + 1, PS_TYPE_F32);
+    newHist->bounds->n = newHist->bounds->nalloc;
+
+    // Calculate the bounds for each bin.
+    binSize = (upper - lower) / (float)n;
+    // NOTE: Is the following necessary? It prevents the max data point
+    // from being in a non-existant bin.
+    binSize += FLT_EPSILON;
+    for (i = 0; i < n + 1; i++) {
+        newHist->bounds->data.F32[i] = lower + (binSize * (float)i);
+    }
+
+    // Allocate the bins, and initialize them to zero.
+    newHist->nums = psVectorAlloc(n, PS_TYPE_U32);
+    newHist->nums->n = newHist->nums->nalloc;
+    for (i = 0; i < newHist->nums->n; i++) {
+        newHist->nums->data.U32[i] = 0;
+    }
+
+    // Initialize the other members.
+    newHist->minNum = 0;
+    newHist->maxNum = 0;
+    newHist->uniform = true;
+
+    return (newHist);
+}
+
+/******************************************************************************
+psHistogramAllocGenric(bounds): allocate a non-uniform histogram structure
+with the specifed bounds.
+ 
+Input:
+    bounds
+Returns:
+    The histogram structure
+ *****************************************************************************/
+psHistogram* psHistogramAllocGeneric(const psVector* restrict bounds)
+{
+    psHistogram* newHist = NULL;        // The new histogram structure
+    int i;                      // Loop index variable
+
+    // NOTE: Verify that this is the correct action.
+    if (bounds == NULL) {
+        // psAbort(__func__, "psHistogram requested with NULL bounds");
+        return (NULL);
+    }
+    // NOTE: Verify that this is the correct action.
+    if (bounds->n <= 1) {
+        // psAbort(__func__, "psHistogram requested with NULL bounds");
+        return (NULL);
+    }
+
+    if (bounds->type.type != PS_TYPE_F32) {
+        // psAbort(__func__, "psHistogram request a bound which is not type F32");
+        return (NULL);
+    }
+    // Allocate memory for the new histogram structure.
+    newHist = (psHistogram* ) psAlloc(sizeof(psHistogram));
+    p_psMemSetDeallocator(newHist, (psFreeFcn) histogramFree);
+    newHist->bounds = psVectorAlloc(bounds->n, PS_TYPE_F32);
+    newHist->bounds->n = newHist->bounds->nalloc;
+    for (i = 0; i < bounds->n; i++) {
+        newHist->bounds->data.F32[i] = bounds->data.F32[i];
+    }
+
+    // Allocate the bins, and initialize them to zero.  If there are N bounds,
+    // then there are N-1 bins.
+    newHist->nums = psVectorAlloc((bounds->n) - 1, PS_TYPE_U32);
+    newHist->nums->n = newHist->nums->nalloc;
+    for (i = 0; i < newHist->nums->n; i++) {
+        newHist->nums->data.U32[i] = 0;
+    }
+
+    // Initialize the other members.
+    newHist->minNum = 0;
+    newHist->maxNum = 0;
+    newHist->uniform = false;
+
+    return (newHist);
+}
+
+static void histogramFree(psHistogram* myHist)
+{
+    psFree(myHist->bounds);
+    psFree(myHist->nums);
+}
+
+/*****************************************************************************
+psVectorHistogram(out, in, mask, maskVal): this procedure takes as input a
+preallocated and initialized histogram structure.  It fills the bins in that
+histogram structure in accordance with the input data "in" and the, possibly
+NULL, mask vector.
+ 
+Inputs:
+    out
+    in
+    mask
+    maskVal
+Returns:
+    The histogram structure "out".
+ *****************************************************************************/
+psHistogram* psVectorHistogram(psHistogram* out,
+                               const psVector* restrict in,
+                               const psVector* restrict mask,
+                               unsigned int maskVal)
+{
+    int i = 0;                  // Loop index variable
+    float binSize = 0.0;        // Histogram bin size
+    int binNum = 0;             // A temporary bin number
+    int numBins = 0;            // The total number of bins
+    int tmp = 0;
+    psScalar tmpScalar;
+    tmpScalar.type.type = PS_TYPE_F32;
+
+    // NOTE: Verify that this is the correct action.
+    if (out == NULL) {
+        return (NULL);
+    }
+    // Check the specified output histogram for type psF32
+    if (out->bounds->type.type != PS_TYPE_F32) {
+        psAbort(__func__, "Only data type PS_TYPE_F32 for the output.bounds member.");
+    }
+
+    if (out->nums->type.type != PS_TYPE_U32) {
+        psAbort(__func__, "Only data type PS_TYPE_U32 for output.nums member.");
+    }
+    // NOTE: Verify that this is the correct action.
+    if (in == NULL) {
+        return (out);
+    }
+
+    if (in->type.type != PS_TYPE_F32) {
+        psAbort(__func__, "Only data type PS_TYPE_F32 is currently supported (0x%x).", in->type.type);
+    }
+
+    if (mask != NULL) {
+        if (in->n != mask->n) {
+            psAbort(__func__, "Vector data and vector mask are of different sizes.");
+        }
+        if (mask->type.type != PS_TYPE_U8) {
+            psAbort(__func__, "Vector mask must be type PS_TYPE_U8");
+        }
+    }
+
+    // NOTE: determine the correct action for a variety of other cases:
+    // in vector has 0 elements, and histogram structure has zero bins.
+
+    numBins = out->nums->n;
+    for (i = 0; i < in->n; i++) {
+        // Check if this pixel is masked, and if so, skip it.
+        if ((mask == NULL) || ((mask != NULL) && (!(mask->data.U8[i] & maskVal)))) {
+            // Check if this pixel is below the minimum value, and if so
+            // count it, then skip it.
+            if (in->data.F32[i] < out->bounds->data.F32[0]) {
+                out->minNum++;
+                // Check if this pixel is above the maximum value, and if so
+                // count it, then skip it.
+            } else if (in->data.F32[i] > out->bounds->data.F32[numBins]) {
+                out->maxNum++;
+            } else {
+                // If this is a uniform histogram, determining the correct
+                // number is trivial.
+                if (out->uniform == true) {
+                    binSize = out->bounds->data.F32[1] - out->bounds->data.F32[0];
+                    binNum = (int)((in->data.F32[i] - out->bounds->data.F32[0]) / binSize);
+
+                    // NOTE: This next if-statement really shouldn't be necessary.
+                    // However, do to numerical lack of precision, we occasionally
+                    // produce a binNum outside the range of bins.
+                    if (binNum >= out->nums->n) {
+                        binNum = out->nums->n - 1;
+                    }
+
+                    (out->nums->data.S32[binNum])++;
+
+                    // If this is a non-uniform histogram, determining the correct
+                    // bin number requires a bit more work.
+                } else {
+                    tmpScalar.data.F32 = in->data.F32[i];
+                    tmp = p_psVectorBinDisect(out->bounds,
+                                              &tmpScalar);
+                    if (tmp == -1) {
+                        //                      XXX: Generate warning message
+                    } else {
+                        (out->nums->data.S32[tmp])++;
+                    }
+                }
+            }
+        }
+    }
+    return (out);
+}
+
+/******************************************************************************
+p_psConvertToF32(myVector, maskVector, maskVal, stats): this is the cheap
+way to support a variety of vector data types: we simply convert the input
+vector to F32 at the beginning, and write all of our functions in F32.  If
+the vast majority of all vector stat operations are F32 (or any other single
+type), then this is probably the best way to go.  Otherwise, when the
+algorithms stablize, we will then macro everything and put type support in
+the various stat functions.
+ 
+XXX: Should the default data type be F64?  Since we are buying Athlons...
+ *****************************************************************************/
+psVector* p_psConvertToF32(psStats* stats, psVector* in, psVector* mask, unsigned int maskVal)
+{
+    int i = 0;
+    psVector* tmp = NULL;
+
+    if (in->type.type == PS_TYPE_S8) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (float)in->data.S8[i];
+        }
+    } else if (in->type.type == PS_TYPE_U16) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (float)in->data.U16[i];
+        }
+    } else if (in->type.type == PS_TYPE_F64) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (float)in->data.F64[i];
+        }
+    } else if (in->type.type == PS_TYPE_F32) {
+        // do nothing
+    } else {
+        psAbort(__func__, "unsupported vector type 0x%x\n", in->type.type);
+    }
+    return (tmp);
+}
+
+/******************************************************************************
+psVectorStats(myVector, maskVector, maskVal, stats): this is the public API
+function which calls the above private stats functions based on what bits
+were set in stats->options.
+ 
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    The stats structure.
+ 
+NOTE: The current strategy is to implement everything assuming that all
+input data is of type PS_TYPE_F32.  Once the basic code is in place, we will
+macro-ize everything and add PS_TYPE_U16 and PS_TYPE_F64.
+ *****************************************************************************/
+psStats* psVectorStats(psStats* stats,
+                       psVector* in,
+                       psVector* mask,
+                       unsigned int maskVal)
+{
+    psVector* inF32;
+    int mustFreeTmp = 1;
+
+    // NOTE: Verify that this is the correct action.
+    if (in == NULL) {
+        return (stats);
+    }
+    if (stats == NULL) {
+        return (NULL);
+    }
+
+    inF32 = p_psConvertToF32(stats, in, mask, maskVal);
+    if (inF32 == NULL) {
+        inF32 = in;
+        mustFreeTmp = 0;
+    }
+    // XXX: Should we abort if (stats->min == stats->max)?
+    if ((stats->options & PS_STAT_USE_RANGE) && (stats->min >= stats->max)) {
+        psAbort(__func__, "psVectorStats() called with range: %f to %f\n", stats->min, stats->max);
+    }
+
+    if (mask != NULL) {
+        PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(mask, in);
+        PS_CHECK_VECTOR_TYPE_RETURN_NULL(mask, PS_TYPE_U8);
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_MEAN) {
+        p_psVectorSampleMean(inF32, mask, maskVal, stats);
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_MEDIAN) {
+        p_psVectorSampleMedian(inF32, mask, maskVal, stats);
+    }
+    // ************************************************************************
+    // NOTE: The Stdev calculation requires the mean.  Should we assume the
+    // mean has already been calculated? Or should we always calculate it?
+    if (stats->options & PS_STAT_SAMPLE_STDEV) {
+        p_psVectorSampleMean(inF32, mask, maskVal, stats);
+        p_psVectorSampleStdev(inF32, mask, maskVal, stats);
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_QUARTILE) {
+        p_psVectorSampleQuartiles(inF32, mask, maskVal, stats);
+    }
+    // Since the various robust stats quantities share much computation, they
+    // are grouped together in a single private function:
+    // p_psVectorRobustStats()
+    if ((stats->options & PS_STAT_ROBUST_MEAN) ||
+            (stats->options & PS_STAT_ROBUST_MEDIAN) ||
+            (stats->options & PS_STAT_ROBUST_MODE) ||
+            (stats->options & PS_STAT_ROBUST_STDEV) || (stats->options & PS_STAT_ROBUST_QUARTILE)) {
+        p_psVectorRobustStats(inF32, mask, maskVal, stats);
+    }
+
+    if ((stats->options & PS_STAT_CLIPPED_MEAN) || (stats->options & PS_STAT_CLIPPED_STDEV)) {
+        p_psVectorClippedStats(inF32, mask, maskVal, stats);
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_MAX) {
+        p_psVectorMax(inF32, mask, maskVal, stats);
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_MIN) {
+        p_psVectorMin(inF32, mask, maskVal, stats);
+    }
+
+    if (mustFreeTmp == 1) {
+        psFree(inF32);
+    }
+    return (stats);
+}
Index: /branches/rel3/psLib/src/dataManip/psStats.h
===================================================================
--- /branches/rel3/psLib/src/dataManip/psStats.h	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/psStats.h	(revision 2163)
@@ -0,0 +1,183 @@
+
+/** @file  psStats.h
+ *  \brief basic statistical operations
+ *  @ingroup Stats
+ *
+ *  This file will hold the definition of the histogram and stats data
+ *  structures.  It also contains prototypes for procedures which operate
+ *  on those data structures.
+ *
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.31 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-06 20:07:04 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_STATS_H)
+#define PS_STATS_H
+
+#include "psVector.h"
+
+/// @addtogroup Stats
+/// @{
+
+/******************************************************************************
+    Statistical functions and data structures.
+ *****************************************************************************/
+
+/** enumeration of statistical calculation options
+ *
+ *  @see psStats, psVectorStats, psImageStats
+ */
+// XXX: Is PS_STAT_ROBUST_FOR_SAMPLE obsolete?
+typedef enum {
+    PS_STAT_SAMPLE_MEAN = 0x000001,
+    PS_STAT_SAMPLE_MEDIAN = 0x000002,
+    PS_STAT_SAMPLE_STDEV = 0x000004,
+    PS_STAT_SAMPLE_QUARTILE = 0x000008,
+    PS_STAT_ROBUST_MEAN = 0x000010,
+    PS_STAT_ROBUST_MEDIAN = 0x000020,
+    PS_STAT_ROBUST_MODE = 0x000040,
+    PS_STAT_ROBUST_STDEV = 0x000080,
+    PS_STAT_ROBUST_QUARTILE = 0x000100,
+    PS_STAT_CLIPPED_MEAN = 0x000200,
+    PS_STAT_CLIPPED_STDEV = 0x000400,
+    PS_STAT_MAX =  0x000800,
+    PS_STAT_MIN =  0x001000,
+    PS_STAT_USE_RANGE =  0x002000,
+    PS_STAT_USE_BINSIZE = 0x004000,
+    PS_STAT_ROBUST_FOR_SAMPLE = 0x008000
+} psStatsOptions;
+
+/** This is the generic statistics structure.  It contails the data members
+    for the various statistic values.  It also contains the options member to
+    specifiy which statistics should be calculated. */
+typedef struct
+{
+    double sampleMean;          ///< formal mean of sample
+    double sampleMedian;        ///< formal median of sample
+    double sampleStdev;         ///< standard deviation of sample
+    double sampleUQ;            ///< upper quartile of sample
+    double sampleLQ;            ///< lower quartile of sample
+    double robustMean;          ///< robust mean of array
+    double robustMedian;        ///< robust median of array
+    double robustMode;          ///< Robust mode of array
+    double robustStdev;         ///< robust standard deviation of array
+    double robustUQ;            ///< robust upper quartile
+    double robustLQ;            ///< robust lower quartile
+    int robustN50;              ///<
+    int robustNfit;             ///<
+    double clippedMean;         ///< Nsigma clipped mean
+    double clippedStdev;        ///< standard deviation after clipping
+    int clippedNvalues;         ///< ???
+    double clipSigma;           ///< Nsigma used for clipping; user input
+    int clipIter;               ///< Number of clipping iterations; user input
+    double min;                 ///< minimum data value in array
+    double max;                 ///< maximum data value in array
+    double binsize;             ///<
+    psStatsOptions options;     ///< bitmask of calculated values
+}
+psStats;
+
+/** Performs statistical calculations on a vector.
+ *
+ *  @return psStats*    the statistical results as specified by stats->options
+ */
+psStats* psVectorStats(
+    psStats* stats,    ///< stats structure defines stats to be calculated and how
+    psVector* in,    ///< Vector to be analysed: must be F32
+    psVector* mask,    ///< Ignore elements where (maskVector & maskVal) != 0: must be INT or NULL
+    unsigned int maskVal    ///< Only mask elements with one of these bits set in maskVector
+);
+
+/** Allocator of the psStats structure.
+ *
+ *  @return psStats*    A new psStats struct with the options member set to the
+ *                      value given.
+ */
+psStats* psStatsAlloc(
+    psStatsOptions options             ///< Statistics to calculate
+);
+
+/******************************************************************************
+    Histogram functions and data structures.
+ *****************************************************************************/
+
+/** The basic histogram structure which contains bounds and bins.
+ *
+ *  In this structure, the vector bounds specifies the boundaries of the 
+ *  histogram bins, and must of type psF32, while nums specifies the number 
+ *  of entries in the bin, and must of type psU32. The value of bounds.n must 
+ *  therefore be 1 greater than than nums.n. The two values minNum and maxNum 
+ *  are the number of data values which fell below the lower limit bound or 
+ *  above the upper limit bound, respectively.
+ */
+typedef struct
+{
+    psVector* bounds;                  ///< Bounds for the bins (type F32)
+    psVector* nums;                    ///< Number in each of the bins (INT)
+    int minNum;                        ///< Number below the minimum
+    int maxNum;                        ///< Number above the maximum
+    bool uniform;                      ///< Is it a uniform distribution?
+}
+psHistogram;
+
+/** Allocator for psHistogram where the bounds of the bins are implicitly
+ *  specified through simply specifying an upper and lower limit along with 
+ *  the size of the bins. 
+ *
+ *  @return psHistogram*    Newly allocated psHistogram
+ */
+psHistogram* psHistogramAlloc(
+    float lower,                       ///< Lower limit for the bins
+    float upper,                       ///< Upper limit for the bins
+    int n                              ///< Number of bins
+);
+
+/** Allocator for psHistogram where the bounds of the bins are explicitly
+ *  specified. 
+ *
+ *  @return psHistogram*    Newly allocated psHistogram
+ */
+psHistogram* psHistogramAllocGeneric(
+    const psVector* restrict bounds    ///< Bounds for the bins
+);
+
+/** Calculate a histogram
+ *
+ *  The following function populates the histogram bins from the specified 
+ *  vector (in). It alters and returns the histogram out structure. The input
+ *  vector may be of types psU8, psU16, psF32, psF64.
+ *
+ *  @return psHistogram*   histogram result
+ */
+psHistogram* psVectorHistogram(
+    psHistogram* out,                  ///< Histogram data
+    const psVector* restrict in,       ///< Vector to analyse
+    const psVector* restrict mask,     ///< Mask dat for input vector
+    unsigned int maskVal               ///< Mask value
+);
+
+/** Extracts the statistic value specified by stats->options.
+ *
+ *  @return bool    If more than one statistic result is set in stats->options,
+ *                  false is returned and the value parameter is not set, 
+ *                  otherwise true is returned.
+ */
+bool p_psGetStatValue(
+    const psStats* stats,
+    ///< the statistic struct to operate on
+
+    double *value
+    ///< if return is true, this is set to the specified statistic value by stats->options
+);
+
+
+void p_psNormalizeVector(psVector* myData);
+
+void p_psNormalizeVectorF64(psVector* myData);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/dataManip/psVectorFFT.c
===================================================================
--- /branches/rel3/psLib/src/dataManip/psVectorFFT.c	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/psVectorFFT.c	(revision 2163)
@@ -0,0 +1,426 @@
+/** @file  psVectorFFT.c
+ *
+ *  @brief Contains FFT transform related functions for psVector
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-13 20:46:57 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <unistd.h>
+#include <stdbool.h>
+#include <string.h>
+#include <complex.h>
+#include <fftw3.h>
+
+#include "psVectorFFT.h"
+#include "psError.h"
+#include "psMemory.h"
+#include "psLogMsg.h"
+#include "psImageExtraction.h"
+
+#include "psDataManipErrors.h"
+
+#define P_FFTW_PLAN_RIGOR FFTW_ESTIMATE
+
+static bool p_fftwWisdomImported = false;
+
+psVector* psVectorFFT(psVector* out, const psVector* in, psFftDirection direction)
+{
+    unsigned int numElements;
+    psElemType type;
+    fftwf_plan plan;
+
+    /* got good image data? */
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+
+    /* make sure the system-level wisdom information is imported. */
+    if (!p_fftwWisdomImported) {
+        fftwf_import_system_wisdom();
+        p_fftwWisdomImported = true;
+    }
+
+    numElements = in->n;
+
+    out = psVectorCopy(out, in, PS_TYPE_C32);
+    out->n = numElements;
+
+    if ((direction & PS_FFT_FORWARD) != 0) {
+        plan = fftwf_plan_dft_1d(numElements,
+                                 (fftwf_complex *) out->data.C32,
+                                 (fftwf_complex *) out->data.C32, FFTW_FORWARD, P_FFTW_PLAN_RIGOR);
+    } else if ((direction & PS_FFT_REVERSE) != 0) {
+        plan = fftwf_plan_dft_1d(numElements,
+                                 (fftwf_complex *) out->data.C32,
+                                 (fftwf_complex *) out->data.C32, FFTW_BACKWARD, P_FFTW_PLAN_RIGOR);
+    } else {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorFFT",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psVectorFFT_DIRECTION_NOTSET);
+        psFree(out);
+        return NULL;
+    }
+
+    /* check if a plan exists now */
+    if (plan == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorFFT",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVectorFFT_FFTW_PLAN_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    /* finally, call FFTW with the plan made above */
+    fftwf_execute(plan);
+
+    fftwf_destroy_plan(plan);
+
+    if ((direction & PS_FFT_REAL_RESULT) != 0) {
+        for (int i = 0; i < numElements; i++) {
+            out->data.F32[i] = out->data.C32[i];
+        }
+        out->type.type = PS_TYPE_F32;
+        out->data.V = psRealloc(out->data.V,PSELEMTYPE_SIZEOF(PS_TYPE_F32)*out->nalloc);
+    }
+
+    return out;
+}
+
+psVector* psVectorReal(psVector* out, const psVector* in)
+{
+    psElemType type;
+    unsigned int numElements;
+
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numElements = in->n;
+
+    /* if not a complex number, this is logically just a copy */
+    if (!PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__, PS_LOG_WARN, "Real portion of a non-Complex type called called for. "
+                 "Just a vector copy was performed.");
+        out = psVectorRecycle(out, numElements, type);
+        out->n = numElements;
+        memcpy(out->data.V, in->data.V, numElements * PSELEMTYPE_SIZEOF(type));
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outVec;
+        psC32* inVec = in->data.C32;
+
+        out = psVectorRecycle(out, numElements, PS_TYPE_F32);
+        out->n = numElements;
+        outVec = out->data.F32;
+
+        for (unsigned int i = 0; i < numElements; i++) {
+            outVec[i] = crealf(inVec[i]);
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outVec;
+        psC64* inVec = in->data.C64;
+
+        out = psVectorRecycle(out, numElements, PS_TYPE_F64);
+        out->n = numElements;
+        outVec = out->data.F64;
+
+        for (unsigned int i = 0; i < numElements; i++) {
+            outVec[i] = creal(inVec[i]);
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorReal",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVectorFFT_TYPE_UNSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector* psVectorImaginary(psVector* out, const psVector* in)
+{
+    psElemType type;
+    unsigned int numElements;
+
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numElements = in->n;
+
+    /* if not a complex number, this is logically just zeroed image of same size */
+    if (!PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__, PS_LOG_WARN, "Imaginary portion of a non-Complex type called for. "
+                 "A zeroed vector was returned.");
+        out = psVectorRecycle(out, numElements, type);
+        out->n = numElements;
+        memset(out->data.V, 0, PSELEMTYPE_SIZEOF(type) * numElements);
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outVec;
+        psC32* inVec = in->data.C32;
+
+        out = psVectorRecycle(out, numElements, PS_TYPE_F32);
+        out->n = numElements;
+        outVec = out->data.F32;
+
+        for (unsigned int i = 0; i < numElements; i++) {
+            outVec[i] = cimagf(inVec[i]);
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outVec;
+        psC64* inVec = in->data.C64;
+
+        out = psVectorRecycle(out, numElements, PS_TYPE_F64);
+        out->n = numElements;
+        outVec = out->data.F64;
+
+        for (unsigned int i = 0; i < numElements; i++) {
+            outVec[i] = cimag(inVec[i]);
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorImaginary",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVectorFFT_TYPE_UNSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector* psVectorComplex(psVector* out, const psVector* real, const psVector* imag)
+{
+    psElemType type;
+    unsigned int numElements;
+
+    if (real == NULL || imag == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = real->type.type;
+    if (real->n < imag->n) {
+        numElements = real->n;
+    } else {
+        numElements = imag->n;
+    }
+
+    if (imag->type.type != type) {
+        char* typeStrReal;
+        char* typeStrImag;
+        PS_TYPE_NAME(typeStrReal,type);
+        PS_TYPE_NAME(typeStrImag,imag->type.type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorComplex",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVectorFFT_REAL_IMAG_TYPE_MISMATCH,
+                   typeStrReal,typeStrImag);
+        psFree(out);
+        return NULL;
+    }
+
+    if (type == PS_TYPE_F32) {
+        psC32* outVec;
+        psF32* realVec = real->data.F32;
+        psF32* imagVec = imag->data.F32;
+
+        out = psVectorRecycle(out, numElements, PS_TYPE_C32);
+        out->n = numElements;
+        outVec = out->data.C32;
+
+        for (unsigned int i = 0; i < numElements; i++) {
+            outVec[i] = realVec[i] + I * imagVec[i];
+        }
+    } else if (type == PS_TYPE_F64) {
+        psC64* outVec;
+        psF64* realVec = real->data.F64;
+        psF64* imagVec = imag->data.F64;
+
+        out = psVectorRecycle(out, numElements, PS_TYPE_C64);
+        out->n = numElements;
+        outVec = out->data.C64;
+
+        for (unsigned int i = 0; i < numElements; i++) {
+            outVec[i] = realVec[i] + I * imagVec[i];
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorComplex",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVectorFFT_NONREAL_NOTSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector* psVectorConjugate(psVector* out, const psVector* in)
+{
+    psElemType type;
+    unsigned int numElements;
+
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numElements = in->n;
+
+    /* if not a complex number, this is logically just a image copy */
+    if (!PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__, PS_LOG_WARN, "Complex Conjugate of a non-Complex type called for. "
+                 "Vector copy was performed instead.");
+
+        out = psVectorRecycle(out, numElements, type);
+        out->n = numElements;
+        memcpy(out->data.V, in->data.V, PSELEMTYPE_SIZEOF(type) * numElements);
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psC32* outVec;
+        psC32* inVec = in->data.C32;
+
+        out = psVectorRecycle(out, numElements, PS_TYPE_C32);
+        out->n = numElements;
+        outVec = out->data.C32;
+
+        for (unsigned int i = 0; i < numElements; i++) {
+            outVec[i] = crealf(inVec[i]) - I * cimagf(inVec[i]);
+        }
+    } else if (type == PS_TYPE_C64) {
+        psC64* outVec;
+        psC64* inVec = in->data.C64;
+
+        out = psVectorRecycle(out, numElements, PS_TYPE_C64);
+        out->n = numElements;
+        outVec = out->data.C64;
+
+        for (unsigned int i = 0; i < numElements; i++) {
+            outVec[i] = creal(inVec[i]) - I * cimag(inVec[i]);
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorConjugate",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVectorFFT_NONCOMPLEX_NOTSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector* psVectorPowerSpectrum(psVector* out, const psVector* in)
+{
+    psElemType type;
+    unsigned int outNumElements;
+    unsigned int inNumElements;
+    unsigned int inHalfNumElements;
+    unsigned int inNumElementsSquared;
+
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    inNumElements = in->n;
+    inNumElementsSquared = inNumElements * inNumElements;
+    inHalfNumElements = inNumElements / 2;
+    outNumElements = inHalfNumElements + 1;
+
+    if (type == PS_TYPE_C32) {
+        psF32* outVec;
+        psC32* inVec = in->data.C32;
+        psF32 inAbs1;
+        psF32 inAbs2;
+
+        out = psVectorRecycle(out, outNumElements, PS_TYPE_F32);
+        out->n = outNumElements;
+        outVec = out->data.F32;
+
+        // from ADD: P_0 = |C_0|^2/N^2
+        inAbs1 = cabsf(inVec[0]);
+        outVec[0] = inAbs1 * inAbs1 / inNumElementsSquared;
+
+        // from ADD: P_j = (|C_j|^2+|C_N-j|^2)/N^2, where j = 1,2,...,(N/2-1)
+        for (unsigned int i = 1; i < inHalfNumElements; i++) {
+            inAbs1 = cabsf(inVec[i]);
+            inAbs2 = cabsf(inVec[inNumElements - i]);
+            outVec[i] = (inAbs1 * inAbs1 + inAbs2 * inAbs2) / inNumElementsSquared;
+        }
+
+        // from ADD: P_N/2 = |C_N/2|^2/N^2
+        inAbs1 = cabsf(inVec[inHalfNumElements]);
+        outVec[inHalfNumElements] = inAbs1 * inAbs1 / inNumElementsSquared;
+    } else if (type == PS_TYPE_C64) {
+        psF64* outVec;
+        psC64* inVec = in->data.C64;
+        psF64 inAbs1;
+        psF64 inAbs2;
+
+        out = psVectorRecycle(out, outNumElements, PS_TYPE_F64);
+        out->n = outNumElements;
+        outVec = out->data.F64;
+
+        // from ADD: P_0 = |C_0|^2/N^2
+        inAbs1 = cabs(inVec[0]);
+        outVec[0] = inAbs1 * inAbs1 / inNumElementsSquared;
+
+        // from ADD: P_j = (|C_j|^2+|C_N-j|^2)/N^2, where j = 1,2,...,(N/2-1)
+        for (unsigned int i = 1; i < inHalfNumElements; i++) {
+            inAbs1 = cabs(inVec[i]);
+            inAbs2 = cabs(inVec[inNumElements - i]);
+            outVec[i] = (inAbs1 * inAbs1 + inAbs2 * inAbs2) / inNumElementsSquared;
+        }
+
+        // from ADD: P_N/2 = |C_N/2|^2/N^2
+        inAbs1 = cabs(inVec[inHalfNumElements]);
+        outVec[inHalfNumElements] = inAbs1 * inAbs1 / inNumElementsSquared;
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorPowerSpectrum",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVectorFFT_NONCOMPLEX_NOTSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+
+}
Index: /branches/rel3/psLib/src/dataManip/psVectorFFT.h
===================================================================
--- /branches/rel3/psLib/src/dataManip/psVectorFFT.h	(revision 2163)
+++ /branches/rel3/psLib/src/dataManip/psVectorFFT.h	(revision 2163)
@@ -0,0 +1,99 @@
+/** @file  psVectorFFT.h
+ *
+ *  @brief Contains FFT transform related functions for psVector
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-06 21:40:13 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_VECTOR_FFT_H
+#define PS_VECTOR_FFT_H
+
+#include "psVector.h"
+
+/// @addtogroup Transform
+/// @{
+
+/** Specify direction of FFT */
+typedef enum {
+    /// psImageFFT/psVectorFFT should perform a forward FFT.
+    PS_FFT_FORWARD = 1,
+
+    /// psImageFFT/psVectorFFT should perform a reverse FFT.
+    PS_FFT_REVERSE = 2,
+
+    /// psImageFFT/psVectorFFT should perform a reverse FFT with a real result.
+    PS_FFT_REAL_RESULT = 4
+} psFftDirection;
+
+
+/** Forward and reverse FFT calculations.
+ *
+ *  This takes as input the vector of interest (in) and the direction 
+ *  (direction), which is specified by an enumerated type psFftDirection.
+ *  The input vector may be of type psF32 or psC32, the result is always 
+ *  psC32. If the input vector is psF32, the direction must be forward. 
+ *  
+ *  @return psVector* the FFT transformation result
+ */
+psVector* psVectorFFT(
+    psVector* out,                     ///< a psVector to recycle.  If NULL, a new psVector is made.
+    const psVector* in,                ///< the vector to apply transform to
+    psFftDirection direction           ///< the direction of the transform
+);
+
+/** extract the real portion of a complex vector
+ * 
+ *  @return psVector*   real portion of the input vector.
+ */
+psVector* psVectorReal(
+    psVector* out,                     ///< a psVector to recycle.  If NULL, a new psVector is made.
+    const psVector* in                ///< the psVector to extract real portion from
+);
+
+/** extract the imaginary portion of a complex vector
+ * 
+ *  @return psVector*   imaginary portion of the input vector.
+ */
+psVector* psVectorImaginary(
+    psVector* out,                     ///< a psVector to recycle.  If NULL, a new psVector is made.
+    const psVector* in                 ///< the psVector to extract imaginary portion from
+);
+
+/** creates a complex vector from separate real and imaginary vectors
+ * 
+ *  @return psVector*   resulting complex vector
+ */
+psVector* psVectorComplex(
+    psVector* out,                     ///< a psVector to recycle.  If NULL, a new psVector is made.
+    const psVector* real,              ///< the real vector
+    const psVector* imag               ///< the imaginary vector
+);
+
+/** computes the complex conjugate of a vector
+ * 
+ *  @return psVector*   the complex conjugate of the 'in' vector
+ */
+psVector* psVectorConjugate(
+    psVector* out,                     ///< a psVector to recycle.  If NULL, a new psVector is made.
+    const psVector* in                 ///< the psVector to compute conjugate of
+);
+
+/** computes the power spectrum of a vector
+ * 
+ *  @return psVector*   the power spectrum of the 'in' vector
+ */
+psVector* psVectorPowerSpectrum(
+    psVector* out,                     ///< a psVector to recycle.  If NULL, a new psVector is made.
+    const psVector* in                 ///< the psVector to power spectrum of
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/fft/psImageFFT.c
===================================================================
--- /branches/rel3/psLib/src/fft/psImageFFT.c	(revision 2163)
+++ /branches/rel3/psLib/src/fft/psImageFFT.c	(revision 2163)
@@ -0,0 +1,447 @@
+/** @file  psImageFFT.c
+ *
+ *  @brief Contains FFT transform related functions for psImage.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-06 21:31:30 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#include <unistd.h>
+#include <stdbool.h>
+#include <string.h>
+#include <complex.h>
+#include <fftw3.h>
+
+#include "psImageFFT.h"
+#include "psError.h"
+#include "psMemory.h"
+#include "psLogMsg.h"
+#include "psImageExtraction.h"
+#include "psImageIO.h"
+
+#include "psImageErrors.h"
+
+#define PS_FFTW_PLAN_RIGOR FFTW_ESTIMATE
+
+static bool p_fftwWisdomImported = false;
+
+psImage* psImageFFT(psImage* out, const psImage* in, psFftDirection direction)
+{
+    unsigned int numCols;
+    unsigned int numRows;
+    psElemType type;
+    fftwf_plan plan;
+
+    /* got good image data? */
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    if ( ((direction & PS_FFT_FORWARD) != 0) ) {
+        if ((direction & PS_FFT_REVERSE) != 0) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageFFT",
+                       PS_ERR_BAD_PARAMETER_VALUE, true,
+                       PS_ERRORTEXT_psImageFFT_FORWARD_REVERSE);
+            psFree(out);
+            return NULL;
+        }
+        if ((direction & PS_FFT_REAL_RESULT) != 0) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageFFT",
+                       PS_ERR_BAD_PARAMETER_VALUE, true,
+                       PS_ERRORTEXT_psImageFFT_REAL_FORWARD_NOTSUPPORTED);
+            psFree(out);
+            return NULL;
+        }
+    } else if ((direction & PS_FFT_REVERSE) == 0) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageFFT",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImageFFT_NO_DIRECTION_OPTION);
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+
+    /* make sure the system-level wisdom information is imported. */
+    if (!p_fftwWisdomImported) {
+        fftwf_import_system_wisdom();
+        p_fftwWisdomImported = true;
+    }
+
+    numRows = in->numRows;
+    numCols = in->numCols;
+
+    // n.b. FFTW can perform a in-place transform at the same rate or faster than out-of-place.
+    int sign = ((direction & PS_FFT_FORWARD) != 0) ? FFTW_FORWARD : FFTW_BACKWARD;
+    out = psImageCopy(out, in, PS_TYPE_C32);
+    plan = fftwf_plan_dft_2d(numCols, numRows,
+                             out->data.C32[0],
+                             out->data.C32[0],
+                             sign,
+                             PS_FFTW_PLAN_RIGOR);
+
+    /* check if a plan exists now -- if not, it is a real problem at this point */
+    if (plan == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageFFT",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImageFFT_FFTW_PLAN_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    /* finally, call FFTW with the plan made above */
+    fftwf_execute(plan);
+
+    fftwf_destroy_plan(plan);
+
+    if (direction & PS_FFT_REAL_RESULT) {
+        // n.b., we do this instead of using fftwf_plan_dft_c2r because that
+        // plan requires a half-image, which would require a image reordering
+        // that is not as simple as performing a normal complex transform and
+        // then taking the real part of the result.  If performance here
+        // becomes an issue, the use of fftwf_plan_dft_r2c should be considered
+        // as well as fftwf_plan_dft_c2r.
+        psImage* realOut = psImageCopy(NULL,out,PS_TYPE_F32);
+        psFree(out);
+        out = realOut;
+    }
+
+    return out;
+
+}
+
+psImage* psImageReal(psImage* out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+
+    /* if not a complex number, this is logically just a copy then */
+    if (!PS_IS_PSELEMTYPE_COMPLEX(type) && type != PS_TYPE_PTR) {
+        return psImageCopy(out, in, type);
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outRow;
+        psC32* inRow;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_F32);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                outRow[col] = crealf(inRow[col]);
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outRow;
+        psC64* inRow;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_F64);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                outRow[col] = creal(inRow[col]);
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageReal",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                   typeStr);
+
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage* psImageImaginary(psImage* out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+
+    /* if not a complex image type, this is logically just zeroed image of same size */
+    if (!PS_IS_PSELEMTYPE_COMPLEX(type) && type != PS_TYPE_PTR) {
+        out = psImageRecycle(out, numCols, numRows, type);
+        memset(out->data.V[0], 0, PSELEMTYPE_SIZEOF(type) * numCols * numRows);
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outRow;
+        psC32* inRow;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_F32);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                outRow[col] = cimagf(inRow[col]);
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outRow;
+        psC64* inRow;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_F64);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                outRow[col] = cimag(inRow[col]);
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageImaginary",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage* psImageComplex(psImage* out, const psImage* real, const psImage* imag)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+    if (real == NULL || imag == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = real->type.type;
+    numCols = real->numCols;
+    numRows = real->numRows;
+
+    if (imag->type.type != type) {
+        char* typeStrReal;
+        char* typeStrImag;
+        PS_TYPE_NAME(typeStrReal,type);
+        PS_TYPE_NAME(typeStrImag,imag->type.type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageComplex",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImageFFT_REAL_IMAG_TYPE_MISMATCH,
+                   typeStrReal,typeStrImag);
+        psFree(out);
+        return NULL;
+    }
+
+    if (imag->numCols != numCols || imag->numRows != numRows) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageComplex",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImageFFT_REAL_IMAG_SIZE_MISMATCH,
+                   numCols, numRows, imag->numCols, imag->numRows);
+        psFree(out);
+        return NULL;
+    }
+
+    if (type == PS_TYPE_F32) {
+        psC32* outRow;
+        psF32* realRow;
+        psF32* imagRow;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_C32);
+
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.C32[row];
+            realRow = real->data.F32[row];
+            imagRow = imag->data.F32[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                outRow[col] = realRow[col] + I * imagRow[col];
+            }
+        }
+    } else if (type == PS_TYPE_F64) {
+        psC64* outRow;
+        psF64* realRow;
+        psF64* imagRow;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_C64);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.C64[row];
+            realRow = real->data.F64[row];
+            imagRow = imag->data.F64[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                outRow[col] = realRow[col] + I * imagRow[col];
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageComplex",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImageFFT_NONREAL_NOTSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+
+    return out;
+}
+
+psImage* psImageConjugate(psImage* out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+
+    /* if not a complex image, this is logically just a image copy */
+    if (!PS_IS_PSELEMTYPE_COMPLEX(type) && type != PS_TYPE_PTR) {
+        return psImageCopy(out, in, type);
+    }
+
+    if (type == PS_TYPE_C32) {
+        psC32* outRow;
+        psC32* inRow;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_C32);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.C32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                outRow[col] = crealf(inRow[col]) - I * cimagf(inRow[col]);
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psC64* outRow;
+        psC64* inRow;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_C64);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.C64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                outRow[col] = creal(inRow[col]) - I * cimag(inRow[col]);
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageConjugate",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImageFFT_NONCOMPLEX_NOTSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage* psImagePowerSpectrum(psImage* out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+    int numElementsSquared;
+
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+    numElementsSquared = numCols * numCols * numRows * numRows;
+
+    if (type == PS_TYPE_C32) {
+        psF32* outRow;
+        psC32* inRow;
+        psF32 real;
+        psF32 imag;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_F32);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                real = crealf(inRow[col]);
+                imag = cimagf(inRow[col]);
+                outRow[col] = (real * real + imag * imag) / numElementsSquared;
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outRow;
+        psC64* inRow;
+        psF64 real;
+        psF64 imag;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_F64);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                real = creal(inRow[col]);
+                imag = cimag(inRow[col]);
+                outRow[col] = (real * real + imag * imag) / numElementsSquared;
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImagePowerSpectrum",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImageFFT_NONCOMPLEX_NOTSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+
+}
Index: /branches/rel3/psLib/src/fft/psImageFFT.h
===================================================================
--- /branches/rel3/psLib/src/fft/psImageFFT.h	(revision 2163)
+++ /branches/rel3/psLib/src/fft/psImageFFT.h	(revision 2163)
@@ -0,0 +1,87 @@
+/** @file  psImageFFT.h
+ *
+ *  @brief Contains FFT transform related functions for psImage
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-25 21:10:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_IMAGE_FFT_H
+#define PS_IMAGE_FFT_H
+
+#include "psImage.h"
+#include "psVectorFFT.h"               // for psFftDirection
+
+/// @addtogroup Transform
+/// @{
+
+/** Forward and reverse FFT calculations.
+ *
+ *  This takes as input the image of interest (in) and the direction 
+ *  (direction), which is specified by an enumerated type psFftDirection.
+ *  The input image may be of type psF32 or psC32, the result is always 
+ *  psC32. If the input vector is psF32, the direction must be forward. 
+ *  
+ *  @return psImage* the FFT transformation result
+ */
+psImage* psImageFFT(
+    psImage* out,                      ///< a psImage to recycle.  If NULL, a new psImage is made.
+    const psImage* in,                 ///< the psImage to apply transform to
+    psFftDirection direction           ///< the direction of the transform
+);
+
+/** extract the real portion of a complex image
+ * 
+ *  @return psImage*   real portion of the input image.
+ */
+psImage* psImageReal(
+    psImage* out,                      ///< a psImage to recycle.  If NULL, a new psImage is made.
+    const psImage* in                  ///< the psImage to extract real portion from
+);
+
+/** extract the imaginary portion of a complex image
+ * 
+ *  @return psImage*   imaginary portion of the input image.
+ */
+psImage* psImageImaginary(
+    psImage* out,                      ///< a psImage to recycle.  If NULL, a new psImage is made.
+    const psImage* in                  ///< the psImage to extract imaginary portion from
+);
+
+/** creates a complex image from separate real and imaginary plane images
+ * 
+ *  @return psImage*   resulting complex image
+ */
+psImage* psImageComplex(
+    psImage* out,                      ///< a psImage to recycle.  If NULL, a new psImage is made.
+    const psImage* real,               ///< the real plane image
+    const psImage* imag                ///< the imaginary plane image
+);
+
+/** computes the complex conjugate of an image
+ * 
+ *  @return psImage*   the complex conjugate of the 'in' image
+ */
+psImage* psImageConjugate(
+    psImage* out,                      ///< a psImage to recycle.  If NULL, a new psImage is made.
+    const psImage* in                  ///< the psImage to compute conjugate of
+);
+
+/** computes the power spectrum of an image
+ * 
+ *  @return psImage*   the power spectrum of the 'in' image
+ */
+psImage* psImagePowerSpectrum(
+    psImage* out,                       ///< a psImage to recycle.  If NULL, a new psImage is made.
+    const psImage* in                   ///< the psImage to power spectrum of
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/fft/psVectorFFT.c
===================================================================
--- /branches/rel3/psLib/src/fft/psVectorFFT.c	(revision 2163)
+++ /branches/rel3/psLib/src/fft/psVectorFFT.c	(revision 2163)
@@ -0,0 +1,426 @@
+/** @file  psVectorFFT.c
+ *
+ *  @brief Contains FFT transform related functions for psVector
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-13 20:46:57 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <unistd.h>
+#include <stdbool.h>
+#include <string.h>
+#include <complex.h>
+#include <fftw3.h>
+
+#include "psVectorFFT.h"
+#include "psError.h"
+#include "psMemory.h"
+#include "psLogMsg.h"
+#include "psImageExtraction.h"
+
+#include "psDataManipErrors.h"
+
+#define P_FFTW_PLAN_RIGOR FFTW_ESTIMATE
+
+static bool p_fftwWisdomImported = false;
+
+psVector* psVectorFFT(psVector* out, const psVector* in, psFftDirection direction)
+{
+    unsigned int numElements;
+    psElemType type;
+    fftwf_plan plan;
+
+    /* got good image data? */
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+
+    /* make sure the system-level wisdom information is imported. */
+    if (!p_fftwWisdomImported) {
+        fftwf_import_system_wisdom();
+        p_fftwWisdomImported = true;
+    }
+
+    numElements = in->n;
+
+    out = psVectorCopy(out, in, PS_TYPE_C32);
+    out->n = numElements;
+
+    if ((direction & PS_FFT_FORWARD) != 0) {
+        plan = fftwf_plan_dft_1d(numElements,
+                                 (fftwf_complex *) out->data.C32,
+                                 (fftwf_complex *) out->data.C32, FFTW_FORWARD, P_FFTW_PLAN_RIGOR);
+    } else if ((direction & PS_FFT_REVERSE) != 0) {
+        plan = fftwf_plan_dft_1d(numElements,
+                                 (fftwf_complex *) out->data.C32,
+                                 (fftwf_complex *) out->data.C32, FFTW_BACKWARD, P_FFTW_PLAN_RIGOR);
+    } else {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorFFT",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psVectorFFT_DIRECTION_NOTSET);
+        psFree(out);
+        return NULL;
+    }
+
+    /* check if a plan exists now */
+    if (plan == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorFFT",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVectorFFT_FFTW_PLAN_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    /* finally, call FFTW with the plan made above */
+    fftwf_execute(plan);
+
+    fftwf_destroy_plan(plan);
+
+    if ((direction & PS_FFT_REAL_RESULT) != 0) {
+        for (int i = 0; i < numElements; i++) {
+            out->data.F32[i] = out->data.C32[i];
+        }
+        out->type.type = PS_TYPE_F32;
+        out->data.V = psRealloc(out->data.V,PSELEMTYPE_SIZEOF(PS_TYPE_F32)*out->nalloc);
+    }
+
+    return out;
+}
+
+psVector* psVectorReal(psVector* out, const psVector* in)
+{
+    psElemType type;
+    unsigned int numElements;
+
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numElements = in->n;
+
+    /* if not a complex number, this is logically just a copy */
+    if (!PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__, PS_LOG_WARN, "Real portion of a non-Complex type called called for. "
+                 "Just a vector copy was performed.");
+        out = psVectorRecycle(out, numElements, type);
+        out->n = numElements;
+        memcpy(out->data.V, in->data.V, numElements * PSELEMTYPE_SIZEOF(type));
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outVec;
+        psC32* inVec = in->data.C32;
+
+        out = psVectorRecycle(out, numElements, PS_TYPE_F32);
+        out->n = numElements;
+        outVec = out->data.F32;
+
+        for (unsigned int i = 0; i < numElements; i++) {
+            outVec[i] = crealf(inVec[i]);
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outVec;
+        psC64* inVec = in->data.C64;
+
+        out = psVectorRecycle(out, numElements, PS_TYPE_F64);
+        out->n = numElements;
+        outVec = out->data.F64;
+
+        for (unsigned int i = 0; i < numElements; i++) {
+            outVec[i] = creal(inVec[i]);
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorReal",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVectorFFT_TYPE_UNSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector* psVectorImaginary(psVector* out, const psVector* in)
+{
+    psElemType type;
+    unsigned int numElements;
+
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numElements = in->n;
+
+    /* if not a complex number, this is logically just zeroed image of same size */
+    if (!PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__, PS_LOG_WARN, "Imaginary portion of a non-Complex type called for. "
+                 "A zeroed vector was returned.");
+        out = psVectorRecycle(out, numElements, type);
+        out->n = numElements;
+        memset(out->data.V, 0, PSELEMTYPE_SIZEOF(type) * numElements);
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outVec;
+        psC32* inVec = in->data.C32;
+
+        out = psVectorRecycle(out, numElements, PS_TYPE_F32);
+        out->n = numElements;
+        outVec = out->data.F32;
+
+        for (unsigned int i = 0; i < numElements; i++) {
+            outVec[i] = cimagf(inVec[i]);
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outVec;
+        psC64* inVec = in->data.C64;
+
+        out = psVectorRecycle(out, numElements, PS_TYPE_F64);
+        out->n = numElements;
+        outVec = out->data.F64;
+
+        for (unsigned int i = 0; i < numElements; i++) {
+            outVec[i] = cimag(inVec[i]);
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorImaginary",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVectorFFT_TYPE_UNSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector* psVectorComplex(psVector* out, const psVector* real, const psVector* imag)
+{
+    psElemType type;
+    unsigned int numElements;
+
+    if (real == NULL || imag == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = real->type.type;
+    if (real->n < imag->n) {
+        numElements = real->n;
+    } else {
+        numElements = imag->n;
+    }
+
+    if (imag->type.type != type) {
+        char* typeStrReal;
+        char* typeStrImag;
+        PS_TYPE_NAME(typeStrReal,type);
+        PS_TYPE_NAME(typeStrImag,imag->type.type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorComplex",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVectorFFT_REAL_IMAG_TYPE_MISMATCH,
+                   typeStrReal,typeStrImag);
+        psFree(out);
+        return NULL;
+    }
+
+    if (type == PS_TYPE_F32) {
+        psC32* outVec;
+        psF32* realVec = real->data.F32;
+        psF32* imagVec = imag->data.F32;
+
+        out = psVectorRecycle(out, numElements, PS_TYPE_C32);
+        out->n = numElements;
+        outVec = out->data.C32;
+
+        for (unsigned int i = 0; i < numElements; i++) {
+            outVec[i] = realVec[i] + I * imagVec[i];
+        }
+    } else if (type == PS_TYPE_F64) {
+        psC64* outVec;
+        psF64* realVec = real->data.F64;
+        psF64* imagVec = imag->data.F64;
+
+        out = psVectorRecycle(out, numElements, PS_TYPE_C64);
+        out->n = numElements;
+        outVec = out->data.C64;
+
+        for (unsigned int i = 0; i < numElements; i++) {
+            outVec[i] = realVec[i] + I * imagVec[i];
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorComplex",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVectorFFT_NONREAL_NOTSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector* psVectorConjugate(psVector* out, const psVector* in)
+{
+    psElemType type;
+    unsigned int numElements;
+
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numElements = in->n;
+
+    /* if not a complex number, this is logically just a image copy */
+    if (!PS_IS_PSELEMTYPE_COMPLEX(type)) {
+        // Warn user, as this is probably not expected
+        psLogMsg(__func__, PS_LOG_WARN, "Complex Conjugate of a non-Complex type called for. "
+                 "Vector copy was performed instead.");
+
+        out = psVectorRecycle(out, numElements, type);
+        out->n = numElements;
+        memcpy(out->data.V, in->data.V, PSELEMTYPE_SIZEOF(type) * numElements);
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psC32* outVec;
+        psC32* inVec = in->data.C32;
+
+        out = psVectorRecycle(out, numElements, PS_TYPE_C32);
+        out->n = numElements;
+        outVec = out->data.C32;
+
+        for (unsigned int i = 0; i < numElements; i++) {
+            outVec[i] = crealf(inVec[i]) - I * cimagf(inVec[i]);
+        }
+    } else if (type == PS_TYPE_C64) {
+        psC64* outVec;
+        psC64* inVec = in->data.C64;
+
+        out = psVectorRecycle(out, numElements, PS_TYPE_C64);
+        out->n = numElements;
+        outVec = out->data.C64;
+
+        for (unsigned int i = 0; i < numElements; i++) {
+            outVec[i] = creal(inVec[i]) - I * cimag(inVec[i]);
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorConjugate",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVectorFFT_NONCOMPLEX_NOTSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psVector* psVectorPowerSpectrum(psVector* out, const psVector* in)
+{
+    psElemType type;
+    unsigned int outNumElements;
+    unsigned int inNumElements;
+    unsigned int inHalfNumElements;
+    unsigned int inNumElementsSquared;
+
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    inNumElements = in->n;
+    inNumElementsSquared = inNumElements * inNumElements;
+    inHalfNumElements = inNumElements / 2;
+    outNumElements = inHalfNumElements + 1;
+
+    if (type == PS_TYPE_C32) {
+        psF32* outVec;
+        psC32* inVec = in->data.C32;
+        psF32 inAbs1;
+        psF32 inAbs2;
+
+        out = psVectorRecycle(out, outNumElements, PS_TYPE_F32);
+        out->n = outNumElements;
+        outVec = out->data.F32;
+
+        // from ADD: P_0 = |C_0|^2/N^2
+        inAbs1 = cabsf(inVec[0]);
+        outVec[0] = inAbs1 * inAbs1 / inNumElementsSquared;
+
+        // from ADD: P_j = (|C_j|^2+|C_N-j|^2)/N^2, where j = 1,2,...,(N/2-1)
+        for (unsigned int i = 1; i < inHalfNumElements; i++) {
+            inAbs1 = cabsf(inVec[i]);
+            inAbs2 = cabsf(inVec[inNumElements - i]);
+            outVec[i] = (inAbs1 * inAbs1 + inAbs2 * inAbs2) / inNumElementsSquared;
+        }
+
+        // from ADD: P_N/2 = |C_N/2|^2/N^2
+        inAbs1 = cabsf(inVec[inHalfNumElements]);
+        outVec[inHalfNumElements] = inAbs1 * inAbs1 / inNumElementsSquared;
+    } else if (type == PS_TYPE_C64) {
+        psF64* outVec;
+        psC64* inVec = in->data.C64;
+        psF64 inAbs1;
+        psF64 inAbs2;
+
+        out = psVectorRecycle(out, outNumElements, PS_TYPE_F64);
+        out->n = outNumElements;
+        outVec = out->data.F64;
+
+        // from ADD: P_0 = |C_0|^2/N^2
+        inAbs1 = cabs(inVec[0]);
+        outVec[0] = inAbs1 * inAbs1 / inNumElementsSquared;
+
+        // from ADD: P_j = (|C_j|^2+|C_N-j|^2)/N^2, where j = 1,2,...,(N/2-1)
+        for (unsigned int i = 1; i < inHalfNumElements; i++) {
+            inAbs1 = cabs(inVec[i]);
+            inAbs2 = cabs(inVec[inNumElements - i]);
+            outVec[i] = (inAbs1 * inAbs1 + inAbs2 * inAbs2) / inNumElementsSquared;
+        }
+
+        // from ADD: P_N/2 = |C_N/2|^2/N^2
+        inAbs1 = cabs(inVec[inHalfNumElements]);
+        outVec[inHalfNumElements] = inAbs1 * inAbs1 / inNumElementsSquared;
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorPowerSpectrum",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVectorFFT_NONCOMPLEX_NOTSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+
+}
Index: /branches/rel3/psLib/src/fft/psVectorFFT.h
===================================================================
--- /branches/rel3/psLib/src/fft/psVectorFFT.h	(revision 2163)
+++ /branches/rel3/psLib/src/fft/psVectorFFT.h	(revision 2163)
@@ -0,0 +1,99 @@
+/** @file  psVectorFFT.h
+ *
+ *  @brief Contains FFT transform related functions for psVector
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-06 21:40:13 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_VECTOR_FFT_H
+#define PS_VECTOR_FFT_H
+
+#include "psVector.h"
+
+/// @addtogroup Transform
+/// @{
+
+/** Specify direction of FFT */
+typedef enum {
+    /// psImageFFT/psVectorFFT should perform a forward FFT.
+    PS_FFT_FORWARD = 1,
+
+    /// psImageFFT/psVectorFFT should perform a reverse FFT.
+    PS_FFT_REVERSE = 2,
+
+    /// psImageFFT/psVectorFFT should perform a reverse FFT with a real result.
+    PS_FFT_REAL_RESULT = 4
+} psFftDirection;
+
+
+/** Forward and reverse FFT calculations.
+ *
+ *  This takes as input the vector of interest (in) and the direction 
+ *  (direction), which is specified by an enumerated type psFftDirection.
+ *  The input vector may be of type psF32 or psC32, the result is always 
+ *  psC32. If the input vector is psF32, the direction must be forward. 
+ *  
+ *  @return psVector* the FFT transformation result
+ */
+psVector* psVectorFFT(
+    psVector* out,                     ///< a psVector to recycle.  If NULL, a new psVector is made.
+    const psVector* in,                ///< the vector to apply transform to
+    psFftDirection direction           ///< the direction of the transform
+);
+
+/** extract the real portion of a complex vector
+ * 
+ *  @return psVector*   real portion of the input vector.
+ */
+psVector* psVectorReal(
+    psVector* out,                     ///< a psVector to recycle.  If NULL, a new psVector is made.
+    const psVector* in                ///< the psVector to extract real portion from
+);
+
+/** extract the imaginary portion of a complex vector
+ * 
+ *  @return psVector*   imaginary portion of the input vector.
+ */
+psVector* psVectorImaginary(
+    psVector* out,                     ///< a psVector to recycle.  If NULL, a new psVector is made.
+    const psVector* in                 ///< the psVector to extract imaginary portion from
+);
+
+/** creates a complex vector from separate real and imaginary vectors
+ * 
+ *  @return psVector*   resulting complex vector
+ */
+psVector* psVectorComplex(
+    psVector* out,                     ///< a psVector to recycle.  If NULL, a new psVector is made.
+    const psVector* real,              ///< the real vector
+    const psVector* imag               ///< the imaginary vector
+);
+
+/** computes the complex conjugate of a vector
+ * 
+ *  @return psVector*   the complex conjugate of the 'in' vector
+ */
+psVector* psVectorConjugate(
+    psVector* out,                     ///< a psVector to recycle.  If NULL, a new psVector is made.
+    const psVector* in                 ///< the psVector to compute conjugate of
+);
+
+/** computes the power spectrum of a vector
+ * 
+ *  @return psVector*   the power spectrum of the 'in' vector
+ */
+psVector* psVectorPowerSpectrum(
+    psVector* out,                     ///< a psVector to recycle.  If NULL, a new psVector is made.
+    const psVector* in                 ///< the psVector to power spectrum of
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/image/Makefile
===================================================================
--- /branches/rel3/psLib/src/image/Makefile	(revision 2163)
+++ /branches/rel3/psLib/src/image/Makefile	(revision 2163)
@@ -0,0 +1,91 @@
+###############################################################################
+##
+##  Makefile:   collections
+##
+##  $Revision: 1.6 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-09-11 00:43:54 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+###############################################################################
+
+# Define variable prefix to the top level project - psLib
+# This is necessary for definition is Makefile.Globals uses prefix
+
+ifndef prefix
+    export prefix=$(shell cd ../..;pwd)
+endif
+
+# Define the two targets to be built
+
+TARGET_STATIC  = libpslib.a
+
+# Include the make global definitions for the project
+
+include ../Makefile.Globals
+
+# Set CFLAGS used by the implicit rule to compile .c
+
+CFLAGS := $(CFLAGS_RELOC) -I../sysUtils -I../dataManip -I../collections -I..
+
+# Define the source objects
+ 
+SRC_OBJS = psImage.o \
+           psImageExtraction.o \
+           psImageIO.o \
+           psImageManip.o \
+           psImageStats.o \
+           psImageFFT.o \
+           psImageConvolve.o 
+
+OBJS = $(addprefix makedir/,$(SRC_OBJS))
+
+HEADERS = $(SRC_OBJS:.o=.h)
+
+# Define PHONY target "all" which will make all the necessary items
+
+all: $(TARGET_STATIC)
+
+psImageErrors.h: psImageErrors.dat
+	perl ../parseErrorCodes.pl --data=$? $@
+
+# Rule to make static library
+
+libpslib.a: $(OBJS)
+# The ar option -r is to add/replace object and -s is to create
+# a symbol table in the archive
+	$(AR) rcs ../$@ $(OBJS)
+
+# Define PHONY target "install" which will install necessary files
+
+install: $(TARGET_STATIC)
+	install $(HEADERS) $(includedir)
+
+# Define PHONY target "distclean" which will cleanup the distribution
+
+distclean:	clean
+	$(RM) ../$(TARGET_STATIC)
+
+# Define PHONY target "clean" which will cleanup the development area
+
+clean:
+	@echo "    Deleting intermediate files for 'collections'"
+	$(RM) $(OBJS) *.lint $(SRC_OBJS:.o=.i)
+
+cleandep:
+	$(RM) $(OBJS:.o=.d)
+
+%.lint: %.c
+	splint +posixlib -exportlocal -realcompare $(INCLUDE_GLOBAL) $? > $@; cat $@
+
+%.i: %.c
+	$(CC) -E $(CFLAGS) -o $@ $<
+
+makedir/%.o: %.c
+	$(CC) -c $(CFLAGS) -o $@ $<
+
+makedir/%.d: %.c
+	$(CC) -MM $(CFLAGS) $< > $@.tmp
+	sed 's|\($*\)\.o[ :]*|\1.o $@ : |g' $@.tmp > $@
+	$(RM) -f $@.tmp
+
+include $(OBJS:.o=.d)
Index: /branches/rel3/psLib/src/image/psImage.c
===================================================================
--- /branches/rel3/psLib/src/image/psImage.c	(revision 2163)
+++ /branches/rel3/psLib/src/image/psImage.c	(revision 2163)
@@ -0,0 +1,697 @@
+
+/** @file  psImage.c
+ *
+ *  @brief Contains basic image definitions and operations.
+ *
+ *  This file defines the basic type for an image struct and functions useful
+ *  in manupulating images.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.50 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 01:22:59 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  That is the routine used to generate matrices.
+ */
+
+#include <string.h>
+#include <math.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psImage.h"
+
+#include "psImageErrors.h"
+
+static void imageFree(psImage* image);
+
+psImage* psImageAlloc(unsigned int numCols,
+                      unsigned int numRows,
+                      const psElemType type)
+{
+    int area = 0;
+    int elementSize = PSELEMTYPE_SIZEOF(type);  // element size in bytes
+    int rowSize = numCols * elementSize;        // row size in bytes.
+
+    area = numCols * numRows;
+
+    if (area < 1) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageAlloc",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImage_AREA_NEGATIVE,
+                   numRows, numCols);
+        return NULL;
+    }
+
+    psImage* image = (psImage* ) psAlloc(sizeof(psImage));
+
+    p_psMemSetDeallocator(image, (psFreeFcn) imageFree);
+
+    image->data.V = psAlloc(sizeof(void *) * numRows);
+
+    image->rawDataBuffer = psAlloc(area * elementSize);
+
+    // set the row pointers.
+    image->data.V[0] = image->rawDataBuffer;
+    for (int i = 1; i < numRows; i++) {
+        image->data.V[i] = (void *)((int8_t *) image->data.V[i - 1] + rowSize);
+    }
+
+    *(int *)&image->col0 = 0;
+    *(int *)&image->row0 = 0;
+    *(unsigned int *)&image->numCols = numCols;
+    *(unsigned int *)&image->numRows = numRows;
+    *(psDimen* ) & image->type.dimen = PS_DIMEN_IMAGE;
+    *(psElemType* ) & image->type.type = type;
+    image->parent = NULL;
+    image->children = NULL;
+
+    return image;
+}
+
+static void imageFree(psImage* image)
+{
+    if (image == NULL) {
+        return;
+    }
+
+    if (image->type.type == PS_TYPE_PTR) {
+        // 2-D array of pointers -- must dereference elements
+        unsigned int oldNumRows = image->numRows;
+        unsigned int oldNumCols = image->numCols;
+        psPTR* rowPtr;
+
+        for (unsigned int row = 0; row < oldNumRows; row++) {
+            rowPtr = image->data.PTR[row];
+            for (unsigned int col = 0; col < oldNumCols; col++) {
+                psMemDecrRefCounter(rowPtr[col]);
+            }
+        }
+    }
+
+    if (image->parent != NULL) {
+        psArrayRemove(image->parent->children,image);
+        image->parent = NULL;
+    }
+
+    psImageFreeChildren(image);
+
+    psFree(image->rawDataBuffer);
+    psFree(image->data.V);
+}
+
+psImage* psImageRecycle(psImage* old,
+                        unsigned int numCols,
+                        unsigned int numRows,
+                        const psElemType type)
+{
+    int elementSize = PSELEMTYPE_SIZEOF(type);  // element size in bytes
+    int rowSize = numCols * elementSize;        // row size in bytes.
+
+    if (old == NULL) {
+        old = psImageAlloc(numCols, numRows, type);
+        return old;
+    }
+
+    if (old->type.dimen != PS_DIMEN_IMAGE) {
+        psFree(old);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRecycle",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImage_NOT_AN_IMAGE);
+        return NULL;
+    }
+
+    if (old->type.type == PS_TYPE_PTR) {
+        // 2-D array of pointers -- must
+        // dereference
+        unsigned int oldNumRows = old->numRows;
+        unsigned int oldNumCols = old->numCols;
+        psPTR* rowPtr;
+
+        for (unsigned int row = 0; row < oldNumRows; row++) {
+            rowPtr = old->data.PTR[row];
+            for (unsigned int col = 0; col < oldNumCols; col++) {
+                psMemDecrRefCounter(rowPtr[col]);
+                rowPtr[col] = NULL;
+            }
+        }
+    }
+
+    /* image already the right size/type? */
+    if (numCols == old->numCols && numRows == old->numRows &&
+            type == old->type.type) {
+        return old;
+    }
+    // Resize the image buffer
+    old->rawDataBuffer = psRealloc(old->data.V[0],
+                                   numCols * numRows * elementSize);
+    old->data.V = (void **)psRealloc(old->data.V, numRows * sizeof(void *));
+
+    // recreate the row pointers
+    old->data.V[0] = old->rawDataBuffer;
+    for (int i = 1; i < numRows; i++) {
+        old->data.V[i] = (void *)((int8_t *) old->data.V[i - 1] + rowSize);
+    }
+
+    *(unsigned int *)&old->numCols = numCols;
+    *(unsigned int *)&old->numRows = numRows;
+    *(psElemType* ) & old->type.type = type;
+
+    return old;
+}
+
+psImage* psImageCopy(psImage* restrict output,
+                     const psImage* input,
+                     psElemType type)
+{
+    psElemType inDatatype;
+    int elementSize;
+    int elements;
+    int numRows;
+    int numCols;
+
+    if (input == NULL || input->data.V == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCopy",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(output);
+        return NULL;
+    }
+
+    if (input == output) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCopy",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_INPLACE_NOTSUPPORTED);
+        psFree(output);
+        return NULL;
+    }
+
+    if (input->type.dimen != PS_DIMEN_IMAGE) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCopy",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImage_NOT_AN_IMAGE);
+        psFree(output);
+        return NULL;
+    }
+
+    inDatatype = input->type.type;
+    numRows = input->numRows;
+    numCols = input->numCols;
+    elements = numRows * numCols;
+    elementSize = PSELEMTYPE_SIZEOF(inDatatype);
+
+    if (inDatatype == PS_TYPE_PTR || type == PS_TYPE_PTR) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCopy",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                   PS_TYPE_PTR_NAME);
+        psFree(output);
+        return NULL;
+    }
+
+    output = psImageRecycle(output, numCols, numRows, type);
+
+    // cover the trival case of copy of the same
+    // datatype.
+    if (type == inDatatype) {
+        for (int row=0;row<numRows;row++) {
+            memcpy(output->data.V[row], input->data.V[row], elementSize * numCols);
+        }
+        return output;
+    }
+
+    #define PSIMAGE_ELEMENT_COPY(IN,INTYPE,OUT,OUTTYPE,ELEMENTS) { \
+        ps##INTYPE *in; \
+        ps##OUTTYPE *out; \
+        for(int row=0;row<numRows;row++) { \
+            in = IN->data.INTYPE[row]; \
+            out = OUT->data.OUTTYPE[row]; \
+            for (int col=0;col<numCols;col++) { \
+                *(out++) = *(in++); \
+            } \
+        } \
+    }
+
+    #define PSIMAGE_COPY_CASE(OUT,OUTTYPE) { \
+        switch (inDatatype) { \
+        case PS_TYPE_S8: \
+            PSIMAGE_ELEMENT_COPY(input,S8,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_S16: \
+            PSIMAGE_ELEMENT_COPY(input,S16,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_S32: \
+            PSIMAGE_ELEMENT_COPY(input,S32,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_S64: \
+            PSIMAGE_ELEMENT_COPY(input,S64,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_U8: \
+            PSIMAGE_ELEMENT_COPY(input,U8,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_U16: \
+            PSIMAGE_ELEMENT_COPY(input,U16,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_U32: \
+            PSIMAGE_ELEMENT_COPY(input,U32,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_U64: \
+            PSIMAGE_ELEMENT_COPY(input,U64,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_F32: \
+            PSIMAGE_ELEMENT_COPY(input,F32,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_F64: \
+            PSIMAGE_ELEMENT_COPY(input,F64,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_C32: \
+            PSIMAGE_ELEMENT_COPY(input,C32,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_C64: \
+            PSIMAGE_ELEMENT_COPY(input,C64,OUT,OUTTYPE,elements); \
+            break; \
+        default: \
+            break; \
+        } \
+    }
+
+    switch (type) {
+    case PS_TYPE_S8:
+        PSIMAGE_COPY_CASE(output, S8);
+        break;
+    case PS_TYPE_S16:
+        PSIMAGE_COPY_CASE(output, S16);
+        break;
+    case PS_TYPE_S32:
+        PSIMAGE_COPY_CASE(output, S32);
+        break;
+    case PS_TYPE_S64:
+        PSIMAGE_COPY_CASE(output, S64);
+        break;
+    case PS_TYPE_U8:
+        PSIMAGE_COPY_CASE(output, U8);
+        break;
+    case PS_TYPE_U16:
+        PSIMAGE_COPY_CASE(output, U16);
+        break;
+    case PS_TYPE_U32:
+        PSIMAGE_COPY_CASE(output, U32);
+        break;
+    case PS_TYPE_U64:
+        PSIMAGE_COPY_CASE(output, U64);
+        break;
+    case PS_TYPE_F32:
+        PSIMAGE_COPY_CASE(output, F32);
+        break;
+    case PS_TYPE_F64:
+        PSIMAGE_COPY_CASE(output, F64);
+        break;
+    case PS_TYPE_C32:
+        PSIMAGE_COPY_CASE(output, C32);
+        break;
+    case PS_TYPE_C64:
+        PSIMAGE_COPY_CASE(output, C64);
+        break;
+    default: {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCopy",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                       typeStr);
+            psFree(output);
+
+            break;
+        }
+    }
+    return output;
+}
+
+int psImageFreeChildren(psImage* image)
+{
+    int numFreed = 0;
+
+    if (image == NULL) {
+        return numFreed;
+    }
+
+    if (image->children != NULL) {
+        psImage** children = (psImage**)image->children->data;
+        numFreed = image->children->n;
+
+        // orphan the children first
+        // (so psFree doesn't try to modify the parent's children array while I'm using it)
+        for (int i=0;i<numFreed;i++) {
+            children[i]->parent = NULL;
+        }
+
+        psFree(image->children);
+        image->children = NULL;
+    }
+
+    return numFreed;
+}
+
+/*****************************************************************************
+p_psImagePixelInterpolation(image, x, y): this routine takes as input an
+image and coordinates (x, y) and produces as output the corresponding pixel
+value at the those coordinates.  For fractional corrdinates (x, y), 2-D
+linear interpolation is performed on the image.
+ *****************************************************************************/
+psC64 psImagePixelInterpolate(const psImage* input,
+                              float x,
+                              float y,
+                              const psImage* mask,
+                              unsigned int maskVal,
+                              psC64 unexposedValue,
+                              psImageInterpolateMode mode)
+{
+
+    if (input == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImagePixelInterpolate",
+                   PS_ERR_BAD_PARAMETER_NULL,true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        return unexposedValue;
+    }
+
+    #define PSIMAGE_PIXEL_INTERPOLATE_CASE(TYPE)                     \
+case PS_TYPE_##TYPE:                                                 \
+    switch (mode) {                                                  \
+    case PS_INTERPOLATE_FLAT:                                        \
+        return p_psImagePixelInterpolateFLAT_##TYPE(                 \
+                input,                                               \
+                x,                                                   \
+                y,                                                   \
+                mask,                                                \
+                maskVal,                                             \
+                unexposedValue);                                     \
+        break;                                                       \
+    case PS_INTERPOLATE_BILINEAR:                                    \
+        return p_psImagePixelInterpolateBILINEAR_##TYPE(             \
+                input,                                               \
+                x,                                                   \
+                y,                                                   \
+                mask,                                                \
+                maskVal,                                             \
+                unexposedValue);                                     \
+        break;                                                       \
+    default:                                                         \
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImagePixelInterpolate",    \
+                   PS_ERR_BAD_PARAMETER_VALUE,true,                  \
+                   PS_ERRORTEXT_psImage_INTERPOLATE_METHOD_INVALID,  \
+                   mode);                                            \
+    }                                                                \
+    break
+
+    switch (input->type.type) {
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(U8);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(U16);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(U32);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(U64);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(S8);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(S16);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(S32);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(S64);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(F32);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(F64);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(C32);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(C64);
+    default: {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,input->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImagePixelInterpolate",
+                       PS_ERR_BAD_PARAMETER_TYPE,true,
+                       PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                       typeStr);
+        }
+    }
+
+    return unexposedValue;
+}
+
+#define PSIMAGE_PIXEL_INTERPOLATE_FLAT(TYPE) \
+inline psF64 p_psImagePixelInterpolateFLAT_##TYPE(const psImage* input, \
+        float x, \
+        float y, \
+        const psImage* mask, \
+        unsigned int maskVal, \
+        psF64 unexposedValue) \
+{ \
+    int intX = (int) round((psF64)(x) - 0.5 + FLT_EPSILON); \
+    int intY = (int) round((psF64)(y) - 0.5 + FLT_EPSILON); \
+    int lastX = input->numCols - 1; \
+    int lastY = input->numRows - 1; \
+    \
+    if ((intX < 0) || \
+            (intX > lastX) || \
+            (intY < 0) || \
+            (intY > lastY) || \
+            ( (mask!=NULL) && \
+              ((mask->data.PS_TYPE_MASK_DATA[intY][intX] & maskVal) != 0) ) ) { \
+        return unexposedValue; \
+    } \
+    \
+    return input->data.TYPE[intY][intX]; \
+}
+
+#define PSIMAGE_PIXEL_INTERPOLATE_FLAT_COMPLEX(TYPE) \
+inline psC64 p_psImagePixelInterpolateFLAT_##TYPE(const psImage* input, \
+        float x, \
+        float y, \
+        const psImage* mask, \
+        unsigned int maskVal, \
+        psC64 unexposedValue) \
+{ \
+    int intX = (int) round((psF64)(x) - 0.5); \
+    int intY = (int) round((psF64)(y) - 0.5); \
+    int lastX = input->numCols - 1; \
+    int lastY = input->numRows - 1; \
+    \
+    if ((intX < 0) || \
+            (intX > lastX) || \
+            (intY < 0) || \
+            (intY > lastY) || \
+            ( (mask!=NULL) && \
+              ((mask->data.PS_TYPE_MASK_DATA[intY][intX] & maskVal) != 0) ) ) { \
+        return unexposedValue; \
+    } \
+    \
+    return input->data.TYPE[intY][intX]; \
+}
+
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(U8)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(U16)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(U32)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(U64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(S8)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(S16)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(S32)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(S64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(F32)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(F64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT_COMPLEX(C32)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT_COMPLEX(C64)
+
+#define PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(TYPE) \
+inline psF64 p_psImagePixelInterpolateBILINEAR_##TYPE(const psImage* input, \
+        float x, \
+        float y, \
+        const psImage* mask, \
+        unsigned int maskVal, \
+        psF64 unexposedValue) \
+{ \
+    double floorX = floor((psF64)(x) - 0.5); \
+    double floorY = floor((psF64)(y) - 0.5); \
+    psF64 fracX = x - 0.5 - floorX; \
+    psF64 fracY = y - 0.5 - floorY; \
+    int intFloorX = (int) floorX; \
+    int intFloorY = (int) floorY; \
+    int lastX = input->numCols - 1; \
+    int lastY = input->numRows - 1; \
+    ps##TYPE V00; \
+    ps##TYPE V01; \
+    ps##TYPE V10; \
+    ps##TYPE V11; \
+    bool valid00 = false; \
+    bool valid01 = false; \
+    bool valid10 = false; \
+    bool valid11 = false; \
+    \
+    if (intFloorY >= 0 && intFloorY <= lastY) { \
+        if (intFloorX >= 0 && intFloorX <= lastX) { \
+            V00 = input->data.TYPE[intFloorY][intFloorX]; \
+            valid00 = (mask == NULL) || \
+                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY][intFloorX] & maskVal) == 0); \
+        } \
+        if (intFloorX >= -1 && intFloorX < lastX) { \
+            V10 = input->data.TYPE[intFloorY][intFloorX+1]; \
+            valid10 = (mask == NULL) || \
+                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY][intFloorX+1] & maskVal) == 0); \
+        } \
+    } \
+    if (intFloorY >= -1 && intFloorY < lastY) { \
+        if (intFloorX >= 0 && intFloorX <= lastX) { \
+            V01 = input->data.TYPE[intFloorY+1][intFloorX]; \
+            valid01 = (mask == NULL) || \
+                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY+1][intFloorX] & maskVal) == 0); \
+        } \
+        if (intFloorX >= -1 && intFloorX < lastX) { \
+            V11 = input->data.TYPE[intFloorY+1][intFloorX+1]; \
+            valid11 = (mask == NULL) || \
+                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY+1][intFloorX+1] & maskVal) == 0); \
+        } \
+    } \
+    \
+    /* cover likely case of all pixels being valid more efficiently */  \
+    if (valid00 && valid10 && valid01 && valid11) { \
+        /* formula from the ADD */ \
+        psF64 rx = V00 + (V10-V00)*fracX; \
+        return (rx + (V01 + (V11 - V01) * fracX - rx) * fracY); \
+    } \
+    \
+    /* OK, at least one pixel is not valid - need to do it piecemeal */ \
+    \
+    psF64 V0; \
+    bool valid0 = true; \
+    if (valid00 && valid10) { \
+        V0 = V00*(1-fracX)+V10*fracX; \
+    } else if (valid00) { \
+        V0 = V00; \
+    } else if (valid10) { \
+        V0 = V10; \
+    } else { \
+        valid0 = false; \
+    } \
+    \
+    psF64 V1; \
+    bool valid1 = true; \
+    if (valid01 && valid11) { \
+        V1 = V01*(1-fracX)+V11*fracX; \
+    } else if (valid01) { \
+        V1 = V01; \
+    } else if (valid11) { \
+        V1 = V11; \
+    } else { \
+        valid1 = false; \
+    } \
+    \
+    if (valid0 && valid1) { \
+        return ( V0*(1-fracY) + V1*fracY ); \
+    } else if (valid0) { \
+        return V0; \
+    } else if (valid1) { \
+        return V1; \
+    } \
+    \
+    return unexposedValue; \
+}
+
+#define PSIMAGE_PIXEL_INTERPOLATE_BILINEAR_COMPLEX(TYPE) \
+inline psC64 p_psImagePixelInterpolateBILINEAR_##TYPE(const psImage* input, \
+        float x, \
+        float y, \
+        const psImage* mask, \
+        unsigned int maskVal, \
+        psC64 unexposedValue) \
+{ \
+    double floorX = floor((psF64)(x) - 0.5); \
+    double floorY = floor((psF64)(y) - 0.5); \
+    psF64 fracX = x - 0.5 - floorX; \
+    psF64 fracY = y - 0.5 - floorY; \
+    int intFloorX = (int) floorX; \
+    int intFloorY = (int) floorY; \
+    int lastX = input->numCols - 1; \
+    int lastY = input->numRows - 1; \
+    ps##TYPE V00; \
+    ps##TYPE V01; \
+    ps##TYPE V10; \
+    ps##TYPE V11; \
+    bool valid00 = false; \
+    bool valid01 = false; \
+    bool valid10 = false; \
+    bool valid11 = false; \
+    \
+    if (intFloorY >= 0 && intFloorY <= lastY) { \
+        if (intFloorX >= 0 && intFloorX <= lastX) { \
+            V00 = input->data.TYPE[intFloorY][intFloorX]; \
+            valid00 = (mask == NULL) || \
+                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY][intFloorX] & maskVal) == 0); \
+        } \
+        if (intFloorX >= -1 && intFloorX < lastX) { \
+            V10 = input->data.TYPE[intFloorY][intFloorX+1]; \
+            valid10 = (mask == NULL) || \
+                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY][intFloorX+1] & maskVal) == 0); \
+        } \
+    } \
+    if (intFloorY >= -1 && intFloorY < lastY) { \
+        if (intFloorX >= 0 && intFloorX <= lastX) { \
+            V01 = input->data.TYPE[intFloorY+1][intFloorX]; \
+            valid01 = (mask == NULL) || \
+                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY+1][intFloorX] & maskVal) == 0); \
+        } \
+        if (intFloorX >= -1 && intFloorX < lastX) { \
+            V11 = input->data.TYPE[intFloorY+1][intFloorX+1]; \
+            valid11 = (mask == NULL) || \
+                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY+1][intFloorX+1] & maskVal) == 0); \
+        } \
+    } \
+    \
+    /* cover likely case of all pixels being valid */  \
+    if (valid00 && valid10 && valid01 && valid11) { \
+        /* formula from the ADD */ \
+        psC64 rx = V00 + (V10-V00)*fracX; \
+        return (rx + (V01 + (V11 - V01) * fracX - rx) * fracY); \
+    } \
+    \
+    /* OK, at least one pixel is not valid - need to do it piecemeal */ \
+    \
+    psC64 V0; \
+    bool valid0 = true; \
+    if (valid00 && valid10) { \
+        V0 = V00*(1-fracX)+V10*fracX; \
+    } else if (valid00) { \
+        V0 = V00; \
+    } else if (valid10) { \
+        V0 = V10; \
+    } else { \
+        valid0 = false; \
+    } \
+    \
+    psC64 V1; \
+    bool valid1 = true; \
+    if (valid01 && valid11) { \
+        V0 = V01*(1-fracX)+V11*fracX; \
+    } else if (valid01) { \
+        V0 = V01; \
+    } else if (valid11) { \
+        V0 = V11; \
+    } else { \
+        valid1 = false; \
+    } \
+    \
+    if (valid0 && valid1) { \
+        return ( V0*(1-fracY) + V1*fracY ); \
+    } else if (valid0) { \
+        return V0; \
+    } else if (valid1) { \
+        return V1; \
+    } \
+    \
+    return unexposedValue; \
+}
+
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U8)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U16)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U32)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U64)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S8)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S16)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S32)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S64)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F32)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F64)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR_COMPLEX(C32)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR_COMPLEX(C64)
Index: /branches/rel3/psLib/src/image/psImage.h
===================================================================
--- /branches/rel3/psLib/src/image/psImage.h	(revision 2163)
+++ /branches/rel3/psLib/src/image/psImage.h	(revision 2163)
@@ -0,0 +1,190 @@
+/** @file  psImage.h
+ *
+ *  @brief Contains basic image definitions and operations
+ *
+ *  This file defines the basic type for an image struct and functions useful
+ *  in manupulating images.
+ *
+ *  @ingroup Image
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.41 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 01:22:59 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#ifndef PS_IMAGE_H
+#define PS_IMAGE_H
+
+#include <complex.h>
+
+#include "psType.h"
+#include "psArray.h"
+
+/// @addtogroup Image
+/// @{
+
+/** enumeration of options in interpolation
+ *
+ */
+typedef enum {
+    PS_INTERPOLATE_FLAT = 1,           ///< 'flat' interpolation (nearest pixel)
+    PS_INTERPOLATE_BILINEAR,           ///< bi-linear interpolation
+    PS_INTERPOLATE_BICUBIC,            ///< bi-cubic interpolation
+    PS_INTERPOLATE_SINC,               ///< sinc interpolation
+    PS_INTERPOLATE_NUM_MODES           ///< end-marker of list of modes; not a valid interpolation mode
+} psImageInterpolateMode;
+
+/** Basic image data structure.
+ *
+ * Struct for maintaining image data of varying types. It also contains
+ * information about image size, parent images and children images.
+ *
+ */
+typedef struct psImage
+{
+    const psType type;                 ///< Image data type and dimension.
+    const unsigned int numCols;        ///< Number of columns in image
+    const unsigned int numRows;        ///< Number of rows in image.
+    const int col0;                    ///< Column position relative to parent.
+    const int row0;                    ///< Row position relative to parent.
+
+    union {
+        psU8**  U8;                    ///< Unsigned 8-bit integer data.
+        psU16** U16;                   ///< Unsigned 16-bit integer data.
+        psU32** U32;                   ///< Unsigned 32-bit integer data.
+        psU64** U64;                   ///< Unsigned 64-bit integer data.
+        psS8**  S8;                    ///< Signed 8-bit integer data.
+        psS16** S16;                   ///< Signed 16-bit integer data.
+        psS32** S32;                   ///< Signed 32-bit integer data.
+        psS64** S64;                   ///< Signed 64-bit integer data.
+        psF32** F32;                   ///< Single-precision float data.
+        psF64** F64;                   ///< Double-precision float data.
+        psC32** C32;                   ///< Single-precision complex data.
+        psC64** C64;                   ///< Double-precision complex data.
+        psPTR** PTR;                   ///< Void pointers.
+        psPTR*  V;                     ///< Pointer to data.
+    } data;                            ///< Union for data types.
+    const struct psImage* parent;      ///< Parent, if a subimage.
+    psArray* children;                 ///< Children of this region.
+
+    void* rawDataBuffer;
+}
+psImage;
+
+/** Create an image of the specified size and type.
+ *
+ * Uses psLib memory allocation functions to create an image struct of the
+ * specified size and type.
+ *
+ * @return psImage* : Pointer to psImage.
+ *
+ */
+psImage* psImageAlloc(
+    unsigned int numCols,              ///< Number of rows in image.
+    unsigned int numRows,              ///< Number of columns in image.
+    const psElemType type              ///< Type of data for image.
+);
+
+/** Resize a given image to the given size/type.
+ *
+ *  @return psImage* Resized psImage.
+ *
+ */
+psImage* psImageRecycle(
+    psImage* old,                      ///< the psImage to recycle by resizing image buffer
+    unsigned int numCols,              ///< the desired number of columns in image
+    unsigned int numRows,              ///< the desired number of rows in image
+    const psElemType type              ///< the desired datatype of the image
+);
+
+/** Makes a copy of a psImage
+ *
+ * @return psImage* Copy of the input psImage.  This may not be equal to the
+ * output parameter
+ *
+ */
+psImage* psImageCopy(
+    psImage* restrict output,          ///< if not NULL, a psImage that could be recycled.
+    const psImage* input,              ///< the psImage to copy
+    psElemType type                    ///< the desired datatype of the returned copy
+);
+
+/** Frees all children of a psImage.
+ *
+ *  @return int      Number of children freed.
+ *
+ */
+int psImageFreeChildren(
+    psImage* image                     ///< psImage in which all children shall be deallocated
+);
+
+/** Interpolate image pixel value given floating point coordinates.
+ *
+ *  @return psF32    Pixel value interpolated from image or unexposedValue if
+ *                   given x,y doesn't coorespond to a valid image location
+ */
+psC64 psImagePixelInterpolate(
+    const psImage* input,              ///< input image for interpolation
+    float x,                           ///< column location to derive value of
+    float y,                           ///< row location ot derive value of
+    const psImage* mask,               ///< if not NULL, the mask of the input image
+    unsigned int maskVal,              ///< the mask value
+    psC64 unexposedValue,              ///< return value if x,y location is not in image.
+    psImageInterpolateMode mode        ///< interpolation mode
+);
+
+#define p_psImagePixelInterpolateFcns(TYPE) \
+inline psF64 p_psImagePixelInterpolateFLAT_##TYPE( \
+        const psImage* input,          /**< input image for interpolation */ \
+        float x,                       /**< column location to derive value of */ \
+        float y,                       /**< row location ot derive value of */ \
+        const psImage* mask,           /**< if not NULL, the mask of the input image */ \
+        unsigned int maskVal,          /**< the mask value */ \
+        psF64 unexposedValue           /**< return value if x,y location is not in image. */ \
+                                                 ); \
+inline psF64 p_psImagePixelInterpolateBILINEAR_##TYPE( \
+        const psImage* input,          /**< input image for interpolation */ \
+        float x,                       /**< column location to derive value of */ \
+        float y,                       /**< row location ot derive value of */ \
+        const psImage* mask,           /**< if not NULL, the mask of the input image */ \
+        unsigned int maskVal,          /**< the mask value */ \
+        psF64 unexposedValue           /**< return value if x,y location is not in image. */ \
+                                                     );
+
+#define p_psImagePixelInterpolateComplexFcns(TYPE) \
+inline psC64 p_psImagePixelInterpolateFLAT_##TYPE( \
+        const psImage* input,          /**< input image for interpolation */ \
+        float x,                       /**< column location to derive value of */ \
+        float y,                       /**< row location ot derive value of */ \
+        const psImage* mask,           /**< if not NULL, the mask of the input image */ \
+        unsigned int maskVal,          /**< the mask value */ \
+        psC64 unexposedValue           /**< return value if x,y location is not in image. */ \
+                                                 ); \
+inline psC64 p_psImagePixelInterpolateBILINEAR_##TYPE( \
+        const psImage* input,          /**< input image for interpolation */ \
+        float x,                       /**< column location to derive value of */ \
+        float y,                       /**< row location ot derive value of */ \
+        const psImage* mask,           /**< if not NULL, the mask of the input image */ \
+        unsigned int maskVal,          /**< the mask value */ \
+        psC64 unexposedValue           /**< return value if x,y location is not in image. */ \
+                                                     );
+
+p_psImagePixelInterpolateFcns(U8)
+p_psImagePixelInterpolateFcns(U16)
+p_psImagePixelInterpolateFcns(U32)
+p_psImagePixelInterpolateFcns(U64)
+p_psImagePixelInterpolateFcns(S8)
+p_psImagePixelInterpolateFcns(S16)
+p_psImagePixelInterpolateFcns(S32)
+p_psImagePixelInterpolateFcns(S64)
+p_psImagePixelInterpolateFcns(F32)
+p_psImagePixelInterpolateFcns(F64)
+p_psImagePixelInterpolateComplexFcns(C32)
+p_psImagePixelInterpolateComplexFcns(C64)
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/image/psImageConvolve.c
===================================================================
--- /branches/rel3/psLib/src/image/psImageConvolve.c	(revision 2163)
+++ /branches/rel3/psLib/src/image/psImageConvolve.c	(revision 2163)
@@ -0,0 +1,437 @@
+/*  @file  psImageConvolve.c
+ *
+ *  @brief Contains FFT transform related functions for psImage.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-06 21:31:30 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <string.h>
+
+#include "psImageConvolve.h"
+#include "psImageFFT.h"
+#include "psImageExtraction.h"
+#include "psMatrixVectorArithmetic.h"
+#include "psMemory.h"
+#include "psLogMsg.h"
+#include "psError.h"
+#include "psImageIO.h"
+
+#include "psImageErrors.h"
+
+#define FOURIER_PADDING 32 /* padding amount in every side of the image for fourier convolution */
+
+static void freeKernel(psKernel* ptr);
+
+psKernel* psKernelAlloc(int xMin, int xMax, int yMin, int yMax)
+{
+    psKernel* result;
+    int numRows;
+    int numCols;
+
+    // following is explicitly spelled out in the SDRS as a requirement
+    if (yMin > yMax) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "Specified yMin, %d, was greater than yMax, %d.  Values swapped.",
+                 yMin, yMax);
+
+        int temp = yMin;
+        yMin = yMax;
+        yMax = temp;
+    }
+
+    // following is explicitly spelled out in the SDRS as a requirement
+    if (xMin > xMax) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "Specified xMin, %d, was greater than xMax, %d.  Values swapped.",
+                 xMin, xMax);
+
+        int temp = xMin;
+        xMin = xMax;
+        xMax = temp;
+    }
+
+    numRows = yMax - yMin + 1;
+    numCols = xMax - xMin + 1;
+
+    result = psAlloc(sizeof(psKernel));
+    result->xMin = xMin;
+    result->xMax = xMax;
+    result->yMin = yMin;
+    result->yMax = yMax;
+    result->image = psImageAlloc(numCols,numRows,PS_TYPE_KERNEL);
+    memset(result->image->rawDataBuffer,0,numCols*numRows*PSELEMTYPE_SIZEOF(PS_TYPE_KERNEL));
+    result->p_kernelRows = psAlloc(sizeof(psKernelType*)*numRows);
+
+    psKernelType** kernelRows = result->p_kernelRows;
+    psKernelType** imageRows = result->image->data.PS_TYPE_KERNEL_DATA;
+    for (int i = 0; i < numRows; i++) {
+        kernelRows[i] = imageRows[i] - xMin;
+    }
+    result->kernel = kernelRows - yMin;
+
+    p_psMemSetDeallocator(result,(psFreeFcn)freeKernel);
+
+    return result;
+}
+
+void freeKernel(psKernel* ptr)
+{
+    if (ptr != NULL) {
+        psFree(ptr->image);
+        psFree(ptr->p_kernelRows);
+    }
+}
+
+psKernel* psKernelGenerate(const psVector* tShifts,
+                           const psVector* xShifts,
+                           const psVector* yShifts,
+                           bool relative)
+{
+    int x = 0;
+    int y = 0;
+    int t = 0;
+    int deltaT;
+    int oldX;
+    int oldY;
+    int xMin = 0;
+    int xMax = 0;
+    int yMin = 0;
+    int yMax = 0;
+    int length = 0;
+    psKernelType normalizeTime = 1.0;  // fraction of total time for each shift clock
+    psKernel* result = NULL;
+    psKernelType** kernel = NULL;
+
+    // got non-NULL vectors?
+    if (tShifts == NULL || xShifts == NULL || yShifts == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psKernelGenerate",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImageConvolve_SHIFT_NULL);
+        return NULL;
+    }
+
+    // types match?
+    if (xShifts->type.type != yShifts->type.type ||
+            tShifts->type.type != xShifts->type.type) {
+        char* typeXStr;
+        char* typeYStr;
+        char* typeTStr;
+        PS_TYPE_NAME(typeXStr,xShifts->type.type);
+        PS_TYPE_NAME(typeYStr,yShifts->type.type);
+        PS_TYPE_NAME(typeTStr,tShifts->type.type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psKernelGenerate",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImageConvolve_SHIFT_TYPE_MISMATCH,
+                   typeTStr, typeXStr, typeYStr);
+        return NULL;
+    }
+
+    // determine the usable length of the shift vector
+    length = xShifts->n;
+    if (length != yShifts->n ||
+            length != tShifts->n) {
+        psLogMsg(__func__,PS_LOG_WARN,"Shift vectors found to be different sizes.");
+        if (yShifts->n < length) {
+            length = yShifts->n;
+        }
+        if (tShifts->n < length) {
+            length = tShifts->n;
+        }
+    }
+
+    #define KERNEL_GENERATE_CASE(TYPE) \
+case PS_TYPE_##TYPE: { \
+        ps##TYPE *tShiftData = tShifts->data.TYPE; \
+        ps##TYPE *xShiftData = xShifts->data.TYPE; \
+        ps##TYPE *yShiftData = yShifts->data.TYPE; \
+        x = 0; \
+        y = 0; \
+        t = 0; \
+        for (int lcv = 0; lcv < length; lcv++) { \
+            if (relative) { \
+                x += xShiftData[lcv]; \
+                y += yShiftData[lcv]; \
+                t += tShiftData[lcv]; \
+            } else { \
+                x = xShiftData[lcv]; \
+                y = yShiftData[lcv]; \
+                t = tShiftData[lcv]; \
+            } \
+            if (x < xMin) { \
+                xMin = x; \
+            } else if (x > xMax) { \
+                xMax = x; \
+            } \
+            if (y < yMin) { \
+                yMin = y; \
+            } else if (y > yMax) { \
+                yMax = y; \
+            } \
+        } \
+        result = psKernelAlloc(xMin,xMax,yMin,yMax); \
+        kernel = result->kernel; \
+        \
+        normalizeTime = 1.0 / (psKernelType)(t); \
+        x = 0; \
+        y = 0; \
+        t = 0; \
+        for (int i = 0; i < length; i++) { \
+            deltaT = t; \
+            oldX = x; \
+            oldY = y; \
+            if (relative) { \
+                t += tShiftData[i]; \
+                x += xShiftData[i]; \
+                y += yShiftData[i]; \
+            } else { \
+                t = tShiftData[i]; \
+                x = xShiftData[i]; \
+                y = yShiftData[i]; \
+            } \
+            deltaT = t - deltaT; \
+            \
+            kernel[oldY][oldX] += deltaT * normalizeTime; \
+        } \
+        break; \
+    }
+
+    switch (xShifts->type.type) {
+        KERNEL_GENERATE_CASE(U8);
+        KERNEL_GENERATE_CASE(U16);
+        KERNEL_GENERATE_CASE(U32);
+        KERNEL_GENERATE_CASE(U64);
+        KERNEL_GENERATE_CASE(S8);
+        KERNEL_GENERATE_CASE(S16);
+        KERNEL_GENERATE_CASE(S32);
+        KERNEL_GENERATE_CASE(S64);
+        KERNEL_GENERATE_CASE(F32);
+        KERNEL_GENERATE_CASE(F64);
+        KERNEL_GENERATE_CASE(C32);
+        KERNEL_GENERATE_CASE(C64);
+
+    default: {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,xShifts->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psKernelGenerate",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                       typeStr);
+        }
+    }
+
+    return result;
+}
+
+psImage* psImageConvolve(psImage* out, const psImage* in, const psKernel* kernel, bool direct)
+{
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    if (kernel == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageConvolve",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImageConvolve_KERNEL_NULL);
+        psFree(out);
+        return NULL;
+    }
+    int xMin = kernel->xMin;
+    int xMax = kernel->xMax;
+    int yMin = kernel->yMin;
+    int yMax = kernel->yMax;
+    psKernelType** kData = kernel->kernel;
+
+    // make the output image to the proper size and type
+    int numRows = in->numRows;
+    int numCols = in->numCols;
+
+
+
+    if (direct) {
+        // spatial convolution
+
+        #define SPATIAL_CONVOLVE_CASE(TYPE) \
+    case PS_TYPE_##TYPE: { \
+            ps##TYPE** inData = in->data.TYPE; \
+            out = psImageRecycle(out, numCols, numRows, PS_TYPE_##TYPE); \
+            for (int row=0;row<numRows;row++) { \
+                ps##TYPE* outRow = out->data.TYPE[row]; \
+                for (int col=0;col<numCols;col++) { \
+                    ps##TYPE pixel = 0.0; \
+                    for (int kRow = yMin; kRow < yMax; kRow++) { \
+                        if (row-kRow >= 0 && row-kRow < numRows) { \
+                            for (int kCol = xMin; kCol < xMax; kCol++) { \
+                                if (col-kCol >= 0 && col-kCol < numCols) { \
+                                    pixel += kData[kRow][kCol] * inData[row-kRow][col-kCol]; \
+                                } \
+                            } \
+                        } \
+                    } \
+                    outRow[col] = pixel; \
+                } \
+            } \
+        } \
+        break;
+
+        switch (in->type.type) {
+            SPATIAL_CONVOLVE_CASE(U8)
+            SPATIAL_CONVOLVE_CASE(U16)
+            SPATIAL_CONVOLVE_CASE(U32)
+            SPATIAL_CONVOLVE_CASE(U64)
+            SPATIAL_CONVOLVE_CASE(S8)
+            SPATIAL_CONVOLVE_CASE(S16)
+            SPATIAL_CONVOLVE_CASE(S32)
+            SPATIAL_CONVOLVE_CASE(S64)
+            SPATIAL_CONVOLVE_CASE(F32)
+            SPATIAL_CONVOLVE_CASE(F64)
+            SPATIAL_CONVOLVE_CASE(C32)
+            SPATIAL_CONVOLVE_CASE(C64)
+
+        default: {
+                char* typeStr;
+                PS_TYPE_NAME(typeStr,in->type.type);
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageConvolve",
+                           PS_ERR_BAD_PARAMETER_TYPE, true,
+                           PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                           typeStr);
+                psFree(out);
+                return NULL;
+
+            }
+        }
+
+
+    } else {
+        // fourier convolution
+        int paddedCols = numCols+2*FOURIER_PADDING;
+        int paddedRows = numRows+2*FOURIER_PADDING;
+
+        // check to see if kernel is smaller, otherwise padding it up will fail.
+        int kRows = kernel->image->numRows;
+        int kCols = kernel->image->numCols;
+        if (kRows >= numRows || kCols >= numCols) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageConvolve",
+                       PS_ERR_BAD_PARAMETER_SIZE, true,
+                       PS_ERRORTEXT_psImageConvolve_KERNEL_TOO_LARGE,
+                       kCols,kRows,
+                       numCols, numRows);
+            psFree(out);
+            return NULL;
+        }
+
+        // pad the image
+        psImage* paddedImage = psImageAlloc(paddedCols,paddedRows,in->type.type);
+        int elementSize = PSELEMTYPE_SIZEOF(in->type.type);
+
+        // zero out padded area on top and bottom
+        memset(paddedImage->data.U8[0],0,FOURIER_PADDING*paddedCols*elementSize);
+        memset(paddedImage->data.U8[FOURIER_PADDING+numRows-1],0,FOURIER_PADDING*paddedCols*elementSize);
+
+        // fill in the image-containing rows.
+        int sidePaddingSize = FOURIER_PADDING*elementSize;
+        int imageRowSize = numCols*elementSize;
+        psU8* paddedData = paddedImage->data.U8[FOURIER_PADDING];
+        for (int row=0;row<numRows;row++) {
+            // zero out padded area on left edge.
+            memset(paddedData,0,sidePaddingSize);
+            paddedData += sidePaddingSize;
+            memcpy(paddedData,in->data.U8[row],imageRowSize);
+            paddedData += imageRowSize;
+            // zero out padded area on right edge.
+            memset(paddedData,0,sidePaddingSize);
+            paddedData += sidePaddingSize;
+        }
+
+        psImageWriteSection(paddedImage,0,0,0,NULL,0,"paddedImage.fits");
+
+        // pad the kernel to the same size of paddedImage
+        psImage* paddedKernel = psImageAlloc(paddedCols,paddedRows,PS_TYPE_KERNEL);
+        memset(paddedKernel->data.U8[0],0,sizeof(psKernelType)*numCols*numRows); // zero-out image
+        int yMax = kernel->yMax;
+        int xMax = kernel->xMax;
+        for (int row = kernel->yMin; row <= yMax;row++) {
+            int padRow = row;
+            if (padRow < 0) {
+                padRow += paddedRows;
+            }
+            psKernelType* padData = paddedKernel->data.PS_TYPE_KERNEL_DATA[padRow];
+            psKernelType* kernelRow = kernel->kernel[row];
+            for (int col = kernel->xMin; col <= xMax; col++) {
+                if (col < 0) {
+                    padData[col+paddedCols] = kernelRow[col];
+                } else {
+                    padData[col] = kernelRow[col];
+                }
+            }
+        }
+
+        psImageWriteSection(paddedKernel,0,0,0,NULL,0,"paddedKernel.fits");
+
+        psImage* kernelFourier = psImageFFT(NULL, paddedKernel, PS_FFT_FORWARD);
+        if (kernelFourier == NULL) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageConvolve",
+                       PS_ERR_UNKNOWN, false,
+                       PS_ERRORTEXT_psImageConvolve_KERNEL_FFT_FAILED);
+            psFree(out);
+            return NULL;
+        }
+
+        psImage* inFourier = psImageFFT(NULL, paddedImage, PS_FFT_FORWARD);
+        if (inFourier == NULL) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageConvolve",
+                       PS_ERR_UNKNOWN, false,
+                       PS_ERRORTEXT_psImageConvolve_FFT_FAILED);
+            psFree(out);
+            return NULL;
+        }
+
+        // convolution in fourier domain is just a pixel-wise multiplication
+        psBinaryOp(inFourier,inFourier,"*",kernelFourier);
+
+        psImage* complexOut = psImageFFT(NULL, inFourier,
+                                         PS_FFT_REVERSE);
+        if (complexOut == NULL) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageConvolve",
+                       PS_ERR_UNKNOWN, false,
+                       PS_ERRORTEXT_psImageConvolve_FFT_FAILED);
+            psFree(out);
+            return NULL;
+        }
+
+        {
+            psImage* tmp = psImageReal(NULL,complexOut);
+            psImageWriteSection(tmp,0,0,0,NULL,0,"complexOut.fits");
+            psFree(tmp);
+        }
+
+        // subset out the padded area now.
+        psImage* complexOutSansPad = psImageSubset(complexOut,
+                                     FOURIER_PADDING,FOURIER_PADDING,
+                                     FOURIER_PADDING+numCols,FOURIER_PADDING+numRows);
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F32);
+        float factor = 1.0f/numCols/numRows;
+        for (int row = 0; row < numRows; row++) {
+            psF32* outRow = out->data.F32[row];
+            psC32* resultRow = complexOutSansPad->data.C32[row];
+            for (int col = 0; col < numCols; col++) {
+                outRow[col] = crealf(resultRow[col])*factor;
+            }
+        }
+
+        psFree(complexOut); // frees complexOutSansPad, as it is a child.
+        psFree(kernelFourier);
+        psFree(inFourier);
+        psFree(paddedImage);
+        psFree(paddedKernel);
+
+    }
+
+    return out;
+}
Index: /branches/rel3/psLib/src/image/psImageConvolve.h
===================================================================
--- /branches/rel3/psLib/src/image/psImageConvolve.h	(revision 2163)
+++ /branches/rel3/psLib/src/image/psImageConvolve.h	(revision 2163)
@@ -0,0 +1,123 @@
+/** @file  psImageConvolve.h
+ *
+ *  @brief image convolution functionality
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-23 18:30:57 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_IMAGE_CONVOLVE_H
+#define PS_IMAGE_CONVOLVE_H
+
+#include<stdbool.h>
+
+#include "psImage.h"
+#include "psVector.h"
+#include "psType.h"
+
+#define PS_TYPE_KERNEL PS_TYPE_F32     /**< the data member to use for kernel image */
+#define PS_TYPE_KERNEL_DATA F32        /**< the data member to use for kernel image */
+#define PS_TYPE_KERNEL_NAME "psF32"    /**< the data type for kernel as a string */
+
+typedef psF32 psKernelType;
+
+/** A convolution kernel */
+typedef struct
+{
+    psImage* image;                    ///< Kernel data, in the form of an image
+    int xMin;                          ///< Most negative x index
+    int yMin;                          ///< Most negative y index
+    int xMax;                          ///< Most positive x index
+    int yMax;                          ///< Most positive y index
+    psKernelType** kernel;             ///< Pointer to the kernel data
+    psKernelType** p_kernelRows;       ///< Pointer to the rows of the kernel data; not intended for user use.
+}
+psKernel;
+
+/** Allocates a convolution kernel of the given range
+ *
+ *  In order to perform a convolution, we need to define the convolution 
+ *  kernel. We need a more general object than a psImage so that we can 
+ *  incorporate the offset from the (0, 0) pixel to the (0, 0) value of the 
+ *  kernel. It might be convenient to allow both positive and negative 
+ *  indices to convey the positive and negative shifts. One might consider 
+ *  setting the x0 and y0 members of a psImage to the appropriate offsets, 
+ *  but this is not the purpose of these members, and doing so may affect the 
+ *  behavior of other psImage operations.
+ *
+ *  This construction allows the kernel member to use negative indices, while 
+ *  preserving the location of psMemBlocks relative to allocated memory.
+ *
+ *  The maximum extent of the kernel shifts shall be defined by the xMin, 
+ *  xMax, yMin and yMax members. Note that xMin and yMin, under normal 
+ *  circumstances, should be negative numbers. That is, 
+ *  myKernel->kernel[-3][-2] may be defined if yMin and xMin are equal to or 
+ *  more negative than -3 and -2, respectively.
+ *
+ *  In the event that one of the minimum values is greater than the 
+ *  corresponding maximum value, the function shall generate a warning, and 
+ *  the offending values shall be exchanged.
+ *
+ *  @return psKernel*          A new kernel object
+ */
+psKernel* psKernelAlloc(
+    int xMin,                          ///< Most negative x index
+    int xMax,                          ///< Most positive x index
+    int yMin,                          ///< Most negative y index
+    int yMax                           ///< Most positive y index
+);
+
+/** Generates a kernel given a list of shift values
+ *
+ *  Given a list of values (e.g., shifts made in the course of OT guiding), 
+ *  psKernelGenerate shall return the appropriate kernel.  The vectors xShifts 
+ *  and yShifts, which are a list of shifts relative to some starting point, 
+ *  will be supplied by the user. The elements of the vectors should be of an 
+ *  integer type; otherwise the values shall be truncated to integers. The 
+ *  output kernel shall be normalized such that the sum over the kernel is 
+ *  unity. 
+ *
+ *  If the vectors are not of the same number of elements, then the function 
+ *  shall generate a warning shall be generated, following which, the longer 
+ *  vector trimmed to the length of the shorter, and the function shall continue.
+ *
+ *  @return psKernel*    new Kernel object
+ */
+psKernel* psKernelGenerate(
+    const psVector* tShifts,           ///< list of time shifts
+    const psVector* xShifts,           ///< list of x-axis shifts
+    const psVector* yShifts,           ///< list of y-axis shifts
+    bool relative
+);
+
+/** convolve an image with a kernel
+ *
+ *  Given an input image and the convolution kernel, psImageConvolve shall 
+ *  convolve the input image, in, with the kernel, kernel and return the 
+ *  convolved image, out.
+ * 
+ *  Two methods shall be available for the convolution: if direct is true, 
+ *  then the convolution shall be performed in real space (appropriate for 
+ *  small kernels); otherwise, the convolution shall be performed using Fast 
+ *  Fourier Transforms (FFTs; appropriate for larger kernels). The latter 
+ *  option involves padding the input image, copying the kernel into an image 
+ *  of the same size as the padded input image, performing an FFT on each, 
+ *  multiplying the FFTs, and performing an inverse FFT before trimming the 
+ *  image back to the original size.
+ *
+ *  @return psImage*  resulting image 
+ */
+psImage* psImageConvolve(
+    psImage* out,                      ///< a psImage to recycle.  If NULL, a new psImage is made.
+    const psImage* in,                 ///< the psImage to convolve
+    const psKernel* kernel,            ///< kernel to colvolve with
+    bool direct                        ///< specifies method, true=direct convolution, false=fourier
+);
+
+#endif
Index: /branches/rel3/psLib/src/image/psImageErrors.dat
===================================================================
--- /branches/rel3/psLib/src/image/psImageErrors.dat	(revision 2163)
+++ /branches/rel3/psLib/src/image/psImageErrors.dat	(revision 2163)
@@ -0,0 +1,79 @@
+#
+#  This file is used to generate psImageErrors.h content
+#
+#  Format is:
+#  ERRORNAME(one word)    ERRORTEXT
+#
+#  N.B. in code, the ERRORNAME appears as PS_ERRORTEXT_ERRORNAME
+####################################################################
+# psImage
+psImage_AREA_NEGATIVE                  Specified number of rows (%d) or columns (%d) is invalid.
+psImage_NOT_AN_IMAGE                   The input psImage must have a PS_DIMEN_IMAGE dimension type.
+psImage_IMAGE_NULL                     Can not operate on a NULL psImage.
+psImage_IMAGE_TYPE_UNSUPPORTED         Specified psImage type, %s, is not supported.
+psImage_INTERPOLATE_METHOD_INVALID     Specified interpolation method (%d) is not supported.
+psImage_SUBSET_RANGE_INVALID           Specified subset range, [%d:%d,%d:%d], is invalid or outside input psImage's boundaries, [0:%d,0:%d].
+psImage_SUBSET_RANGE_MALFORMED         Specified subset range, [%d:%d,%d:%d], is invalid.  Ranges must be incremental.
+psImage_SUBSECTION_NULL                Specified subsection string can not be NULL.
+psImage_SUBSECTION_INVALID             Specified subsection string, '%s', can not be parsed.  Must be in the form '[x1:x2,y1:y2]'.
+psImage_NOT_PARENT                     Specified psImage can not be a child of another psImage.
+psImage_INPLACE_NOTSUPPORTED           Specified input and output psImage can not reference the same psImage.
+psImage_SUBSET_ZERO_SIZE               Specified subset, [%d:%d,%d:%d], contains no pixel data.
+psImage_IMAGE_MASK_SIZE                Input psImage mask size, %dx%d, does not match psImage input size, %dx%d.
+psImage_IMAGE_MASK_TYPE                Input psImage mask type, %s, is not the supported mask datatype of %s.
+psImage_BAD_STAT                       Specified statistic option, %d, is not valid.  Must specify one and only one statistic type.
+psImage_NO_STAT_OPTIONS                Specified statistic option did not indicate any operation to perform.
+psImage_STAT_NULL                      Specified statistic can not be NULL.
+psImage_SLICE_DIRECTION_INVALID        Specified slice direction, %d, is invalid.
+psImage_PARAMETER_OUTOF_TYPERANGE      Specified %s value, %g, is outside of psImage type's range (%s: %g to %g).
+psImage_nSamples_TOOSMALL              Specified number of samples, %d, must be greater than 1 to make a line.
+psImage_LINE_NOT_IN_IMAGE              Specified line, (%f,%f)->(%f,%f), does not entirely lie in psImage's boundaries, [0:%d,0:%d].
+psImage_RADII_VECTOR_NULL              Specified radii vector can not be NULL.
+psImage_CENTER_NOT_IN_IMAGE            Specified center, (%g,%g), is outside of the psImage boundaries, [0:%d,0:%d].
+psImage_RADII_VECTOR_TOOSMALL          Input radii vector size, %d, can not be less than 2.
+#
+psImageFFT_IMAGE_TYPE_UNSUPPORTED      Input psImage type (%s) is not supported. Valid image types are psF32 and psC32.
+psImageFFT_REVERSE_NOT_COMPLEX         Input psImage (%s) is not complex.  Reverse FFT operation requires a complex psImage input.
+psImageFFT_FORWARD_NOT_REAL            Input psImage (%s) is not real.  Forward FFT operation requires a real psImage input.
+psImageFFT_FFTW_PLAN_NULL              Could not create a valid FFT plan to perform the transform.
+psImageFFT_REAL_IMAG_TYPE_MISMATCH     Real psImage type (%s) and imaginary psImage type (%s) must be the same.
+psImageFFT_REAL_IMAG_SIZE_MISMATCH     Real psImage size (%dx%d) and imaginary psImage size (%dx%d) must be the same.
+psImageFFT_NONREAL_NOTSUPPORTED        Input psImage type, %s, is required to be either psF32 or psF64.
+psImageFFT_NONCOMPLEX_NOTSUPPORTED     Input psImage type, %s, is required to be either psC32 or psC64.
+psImageFFT_REAL_FORWARD_NOTSUPPORTED   The PS_FFT_FORWARD and PS_FFT_REAL_RESULT combinition is not supported.
+psImageFFT_FORWARD_REVERSE             Can not specify both PS_FFT_FORWARD and PS_FFT_REVERSE options.
+psImageFFT_NO_DIRECTION_OPTION         Must specify either PS_FFT_FORWARD or PS_FFT_REVERSE option.
+#
+psImageIO_FILENAME_NULL                Specified filename can not be NULL.
+psImageIO_FILENAME_INVALID             Could not open file,'%s'.\nCFITSIO Error: %s
+psImageIO_EXTNAME_INVALID              Could not find HDU with extension name '%s' in file %s.\nCFITSIO Error: %s
+psImageIO_EXTNUM_INVALID               Could not find HDU #%d in file %s.\nCFITSIO Error: %s
+psImageIO_DATATYPE_UNKNOWN             Could not determine image data type for file %s.\nCFITSIO Error: %s
+psImageIO_IMAGE_DIM_UNKNOWN            Could not determine image dimensions for file %s.\nCFITSIO Error: %s
+psImageIO_IMAGE_SIZE_UNKNOWN           Could not determine image size for file %s.\nCFITSIO Error: %s
+psImageIO_IMAGE_DIMENSION_UNSUPPORTED  Image number of dimensions, %d, is not valid.  Only two or three dimensions supported for FITS I/O.
+psImageIO_FITS_TYPE_UNSUPPORTED        FITS image type, BITPIX=%d, in file %s is not supported.
+psImageIO_READ_FAILED                  Reading from FITS file %s failed.\nCFITSIO Error: %s
+psImageIO_TYPE_UNSUPPORTED             Input psImage type, %s, is not supported.
+psImageIO_WRITE_EXTNUM_INVALID         Specified extension number, %d, must not exceed number of HDUs, %d, by more than one.
+psImageIO_FILENAME_CREATE_FAILED       Could not create file,'%s'.\nCFITSIO Error: %s
+psImageIO_CREATE_EXTENSION_FAILED      Could not create EXTNAME keyword for file,'%s'.\nCFITSIO Error: %s
+psImageIO_CREATE_HDU_FAILED            Could not create HDU for writing psImage in file,'%s'.\nCFITSIO Error: %s
+psImageIO_WRITE_FAILED                 Could not write psImage data to file,'%s'.\nCFITSIO Error: %s
+#
+psImageManip_MAXMIN                    Specified min value, %g, can not be greater than the specified max value, %g.
+psImageManip_MAXMIN_REAL               Specified real-portion of min value, %g, can not be greater than the real-portion of max value, %g.
+psImageManip_MAXMIN_IMAG               Specified imaginary-portion of min value, %g, can not be greater than the imaginary-portion of max value, %g.
+psImageManip_OPERATION_NULL            Operation can not be NULL.
+psImageManip_OVERLAY_TYPE_MISMATCH     Input overlay psImage type, %s, must match input psImage type, %s.
+psImageManip_CLIP_VALUE_INVALID        Specified %s value, %g%+gi, is not the the range of input psImage's valid pixel values (%s), i.e. [%g:%g].  
+psImageManip_OVERLAY_OPERATOR_INVALID  Specified operation, '%s', is not supported.
+psImageManip_SCALE_NOT_POSITIVE        Specified scale value, %d, must be a positive value.
+psImageManip_INTERPOLATION_MODE_UNSUPPORTED Specified interpolation mode, %d, is unsupported.
+psImageConvolve_SHIFT_NULL             Specified shift vectors can not be NULL.
+psImageConvolve_KERNEL_NULL            Specified psKernel can not be NULL.
+psImageConvolve_SHIFT_TYPE_MISMATCH    Input t-, x-, and y-shift vector types (%s/%s/%s) must match.
+psImageConvolve_FFT_FAILED             Failed to perform a fourier transform of input image.
+psImageConvolve_KERNEL_FFT_FAILED      Failed to perform a fourier transform of kernel.
+psImageConvolve_KERNEL_TOO_LARGE       Specified psKernel size, %dx%d, can not be larger than input psImage size, %dx%d. 
+psImage_COEFF_NULL                     Polynomial coefficients cannot be NULL. 
Index: /branches/rel3/psLib/src/image/psImageErrors.h
===================================================================
--- /branches/rel3/psLib/src/image/psImageErrors.h	(revision 2163)
+++ /branches/rel3/psLib/src/image/psImageErrors.h	(revision 2163)
@@ -0,0 +1,101 @@
+/** @file  psImageErrors.h
+ *
+ *  @brief Contains the error text for the image functions
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-13 23:34:57 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_IMAGE_ERRORS_H
+#define PS_IMAGE_ERRORS_H
+
+/* N.B., lines between '//~Start' and '//~End' are automatic generated from
+ * the template following the '//~Start'.  The template is used to generate
+ * the other lines by, for each error text in psImageErrors.dat, the following
+ * substitutions are made:
+ *     $1  The error text macro name (first word in the psImageErrors.dat lines)
+ *     $2  The error text (rest of the line in psImageErrors.dat)
+ *     $n  The order of the source line in psImageErrors.dat (comments excluded)
+ * 
+ * DO NOT EDIT THE LINES BETWEEN //~Start and //~End!  ANY CHANGES WILL BE OVERWRITTEN.
+ */
+
+#define PS_ERRORNAME_DOMAIN "psLib.image."
+
+//~Start #define PS_ERRORTEXT_$1 "$2"
+#define PS_ERRORTEXT_psImage_AREA_NEGATIVE "Specified number of rows (%d) or columns (%d) is invalid."
+#define PS_ERRORTEXT_psImage_NOT_AN_IMAGE "The input psImage must have a PS_DIMEN_IMAGE dimension type."
+#define PS_ERRORTEXT_psImage_IMAGE_NULL "Can not operate on a NULL psImage."
+#define PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED "Specified psImage type, %s, is not supported."
+#define PS_ERRORTEXT_psImage_INTERPOLATE_METHOD_INVALID "Specified interpolation method (%d) is not supported."
+#define PS_ERRORTEXT_psImage_SUBSET_RANGE_INVALID "Specified subset range, [%d:%d,%d:%d], is invalid or outside input psImage's boundaries, [0:%d,0:%d]."
+#define PS_ERRORTEXT_psImage_SUBSET_RANGE_MALFORMED "Specified subset range, [%d:%d,%d:%d], is invalid.  Ranges must be incremental."
+#define PS_ERRORTEXT_psImage_SUBSECTION_NULL "Specified subsection string can not be NULL."
+#define PS_ERRORTEXT_psImage_SUBSECTION_INVALID "Specified subsection string, '%s', can not be parsed.  Must be in the form '[x1:x2,y1:y2]'."
+#define PS_ERRORTEXT_psImage_NOT_PARENT "Specified psImage can not be a child of another psImage."
+#define PS_ERRORTEXT_psImage_INPLACE_NOTSUPPORTED "Specified input and output psImage can not reference the same psImage."
+#define PS_ERRORTEXT_psImage_SUBSET_ZERO_SIZE "Specified subset, [%d:%d,%d:%d], contains no pixel data."
+#define PS_ERRORTEXT_psImage_IMAGE_MASK_SIZE "Input psImage mask size, %dx%d, does not match psImage input size, %dx%d."
+#define PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE "Input psImage mask type, %s, is not the supported mask datatype of %s."
+#define PS_ERRORTEXT_psImage_BAD_STAT "Specified statistic option, %d, is not valid.  Must specify one and only one statistic type."
+#define PS_ERRORTEXT_psImage_NO_STAT_OPTIONS "Specified statistic option did not indicate any operation to perform."
+#define PS_ERRORTEXT_psImage_STAT_NULL "Specified statistic can not be NULL."
+#define PS_ERRORTEXT_psImage_SLICE_DIRECTION_INVALID "Specified slice direction, %d, is invalid."
+#define PS_ERRORTEXT_psImage_PARAMETER_OUTOF_TYPERANGE "Specified %s value, %g, is outside of psImage type's range (%s: %g to %g)."
+#define PS_ERRORTEXT_psImage_nSamples_TOOSMALL "Specified number of samples, %d, must be greater than 1 to make a line."
+#define PS_ERRORTEXT_psImage_LINE_NOT_IN_IMAGE "Specified line, (%f,%f)->(%f,%f), does not entirely lie in psImage's boundaries, [0:%d,0:%d]."
+#define PS_ERRORTEXT_psImage_RADII_VECTOR_NULL "Specified radii vector can not be NULL."
+#define PS_ERRORTEXT_psImage_CENTER_NOT_IN_IMAGE "Specified center, (%g,%g), is outside of the psImage boundaries, [0:%d,0:%d]."
+#define PS_ERRORTEXT_psImage_RADII_VECTOR_TOOSMALL "Input radii vector size, %d, can not be less than 2."
+#define PS_ERRORTEXT_psImageFFT_IMAGE_TYPE_UNSUPPORTED "Input psImage type (%s) is not supported. Valid image types are psF32 and psC32."
+#define PS_ERRORTEXT_psImageFFT_REVERSE_NOT_COMPLEX "Input psImage (%s) is not complex.  Reverse FFT operation requires a complex psImage input."
+#define PS_ERRORTEXT_psImageFFT_FORWARD_NOT_REAL "Input psImage (%s) is not real.  Forward FFT operation requires a real psImage input."
+#define PS_ERRORTEXT_psImageFFT_FFTW_PLAN_NULL "Could not create a valid FFT plan to perform the transform."
+#define PS_ERRORTEXT_psImageFFT_REAL_IMAG_TYPE_MISMATCH "Real psImage type (%s) and imaginary psImage type (%s) must be the same."
+#define PS_ERRORTEXT_psImageFFT_REAL_IMAG_SIZE_MISMATCH "Real psImage size (%dx%d) and imaginary psImage size (%dx%d) must be the same."
+#define PS_ERRORTEXT_psImageFFT_NONREAL_NOTSUPPORTED "Input psImage type, %s, is required to be either psF32 or psF64."
+#define PS_ERRORTEXT_psImageFFT_NONCOMPLEX_NOTSUPPORTED "Input psImage type, %s, is required to be either psC32 or psC64."
+#define PS_ERRORTEXT_psImageFFT_REAL_FORWARD_NOTSUPPORTED "The PS_FFT_FORWARD and PS_FFT_REAL_RESULT combinition is not supported."
+#define PS_ERRORTEXT_psImageFFT_FORWARD_REVERSE "Can not specify both PS_FFT_FORWARD and PS_FFT_REVERSE options."
+#define PS_ERRORTEXT_psImageFFT_NO_DIRECTION_OPTION "Must specify either PS_FFT_FORWARD or PS_FFT_REVERSE option."
+#define PS_ERRORTEXT_psImageIO_FILENAME_NULL "Specified filename can not be NULL."
+#define PS_ERRORTEXT_psImageIO_FILENAME_INVALID "Could not open file,'%s'.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psImageIO_EXTNAME_INVALID "Could not find HDU with extension name '%s' in file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psImageIO_EXTNUM_INVALID "Could not find HDU #%d in file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psImageIO_DATATYPE_UNKNOWN "Could not determine image data type for file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psImageIO_IMAGE_DIM_UNKNOWN "Could not determine image dimensions for file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psImageIO_IMAGE_SIZE_UNKNOWN "Could not determine image size for file %s.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psImageIO_IMAGE_DIMENSION_UNSUPPORTED "Image number of dimensions, %d, is not valid.  Only two or three dimensions supported for FITS I/O."
+#define PS_ERRORTEXT_psImageIO_FITS_TYPE_UNSUPPORTED "FITS image type, BITPIX=%d, in file %s is not supported."
+#define PS_ERRORTEXT_psImageIO_READ_FAILED "Reading from FITS file %s failed.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psImageIO_TYPE_UNSUPPORTED "Input psImage type, %s, is not supported."
+#define PS_ERRORTEXT_psImageIO_WRITE_EXTNUM_INVALID "Specified extension number, %d, must not exceed number of HDUs, %d, by more than one."
+#define PS_ERRORTEXT_psImageIO_FILENAME_CREATE_FAILED "Could not create file,'%s'.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psImageIO_CREATE_EXTENSION_FAILED "Could not create EXTNAME keyword for file,'%s'.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psImageIO_CREATE_HDU_FAILED "Could not create HDU for writing psImage in file,'%s'.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psImageIO_WRITE_FAILED "Could not write psImage data to file,'%s'.\nCFITSIO Error: %s"
+#define PS_ERRORTEXT_psImageManip_MAXMIN "Specified min value, %g, can not be greater than the specified max value, %g."
+#define PS_ERRORTEXT_psImageManip_MAXMIN_REAL "Specified real-portion of min value, %g, can not be greater than the real-portion of max value, %g."
+#define PS_ERRORTEXT_psImageManip_MAXMIN_IMAG "Specified imaginary-portion of min value, %g, can not be greater than the imaginary-portion of max value, %g."
+#define PS_ERRORTEXT_psImageManip_OPERATION_NULL "Operation can not be NULL."
+#define PS_ERRORTEXT_psImageManip_OVERLAY_TYPE_MISMATCH "Input overlay psImage type, %s, must match input psImage type, %s."
+#define PS_ERRORTEXT_psImageManip_CLIP_VALUE_INVALID "Specified %s value, %g%+gi, is not the the range of input psImage's valid pixel values (%s), i.e. [%g:%g].  "
+#define PS_ERRORTEXT_psImageManip_OVERLAY_OPERATOR_INVALID "Specified operation, '%s', is not supported."
+#define PS_ERRORTEXT_psImageManip_SCALE_NOT_POSITIVE "Specified scale value, %d, must be a positive value."
+#define PS_ERRORTEXT_psImageManip_INTERPOLATION_MODE_UNSUPPORTED "Specified interpolation mode, %d, is unsupported."
+#define PS_ERRORTEXT_psImageConvolve_SHIFT_NULL "Specified shift vectors can not be NULL."
+#define PS_ERRORTEXT_psImageConvolve_KERNEL_NULL "Specified psKernel can not be NULL."
+#define PS_ERRORTEXT_psImageConvolve_SHIFT_TYPE_MISMATCH "Input t-, x-, and y-shift vector types (%s/%s/%s) must match."
+#define PS_ERRORTEXT_psImageConvolve_FFT_FAILED "Failed to perform a fourier transform of input image."
+#define PS_ERRORTEXT_psImageConvolve_KERNEL_FFT_FAILED "Failed to perform a fourier transform of kernel."
+#define PS_ERRORTEXT_psImageConvolve_KERNEL_TOO_LARGE "Specified psKernel size, %dx%d, can not be larger than input psImage size, %dx%d. "
+#define PS_ERRORTEXT_psImage_COEFF_NULL "Polynomial coefficients cannot be NULL. "
+//~End
+
+#endif
Index: /branches/rel3/psLib/src/image/psImageExtraction.c
===================================================================
--- /branches/rel3/psLib/src/image/psImageExtraction.c	(revision 2163)
+++ /branches/rel3/psLib/src/image/psImageExtraction.c	(revision 2163)
@@ -0,0 +1,843 @@
+/** @file  psImageExtraction.c
+ *
+ *  @brief Contains basic image extraction operations, as specified in the 
+ *         PSLIB SDRS sections "Image Pixel Extractions" and "Image Structure
+ *         Manipulation".
+ *
+ *  @ingroup Image
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 01:22:59 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include <string.h>
+
+#include "psMemory.h"
+#include "psImageExtraction.h"
+#include "psError.h"
+
+#include "psImageErrors.h"
+
+psImage* imageSubset(psImage* out,
+                     psImage* image,
+                     int col0,
+                     int row0,
+                     int col1,
+                     int row1)
+{
+    unsigned int elementSize;          // size of image element in bytes
+    unsigned int inputColOffset;       // offset in bytes to first subset pixel in input row
+
+    if (image == NULL || image->data.V == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageSubset",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        return NULL;
+    }
+
+    if (image->type.dimen != PS_DIMEN_IMAGE) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageSubset",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImage_NOT_AN_IMAGE);
+        return NULL;
+    }
+
+    if (col1 < 1) {
+        col1 = image->numCols + col1;
+    }
+    if (row1 < 1) {
+        row1 = image->numRows + row1;
+    }
+
+    if (    col1 <= col0 ||
+            row1 <= row0 ||
+            col0 >= image->numCols ||
+            row0 >= image->numRows ||
+            col1 > image->numCols ||
+            row1 > image->numRows ) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageSubset",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImage_SUBSET_RANGE_INVALID,
+                   col0, col1-1, row0, row1-1,
+                   image->numCols-1, image->numRows-1);
+        return NULL;
+    }
+    int numRows = row1-row0;
+    int numCols = col1-col0;
+
+    elementSize = PSELEMTYPE_SIZEOF(image->type.type);
+
+    if (image->parent != NULL) { // if this is a child, we need to start working with parent.
+        col0 += image->col0;
+        col1 += image->col0;
+        row0 += image->row0;
+        row1 += image->row0;
+        image = (psImage*)image->parent;
+    }
+
+    // increment the raw data buffer before freeing anything in the 'out'
+    void* rawData = psMemIncrRefCounter(image->rawDataBuffer);
+
+    if (out != NULL) {
+        // if a child, need to orphan (disassociate from parent) first
+        if (out->parent != NULL) {
+            psArrayRemove(out->parent->children,out); // remove from parent's knowledge
+            out->parent = NULL; // break link to parent
+        }
+
+        psFree(out->rawDataBuffer); // free the previous data reference
+    } else {
+        out = psAlloc(sizeof(psImage));
+        out->data.V = NULL;
+    }
+
+    out->data.V = psRealloc(out->data.V,sizeof(void*)*numRows); // resize row pointer array
+    *(psType*)&out->type = image->type;
+    *(unsigned int*)&out->numCols = numCols;
+    *(unsigned int*)&out->numRows = numRows;
+    *(int*)&out->row0 = row0;
+    *(int*)&out->col0 = col0;
+    out->parent = image;
+    out->children = NULL;
+    out->rawDataBuffer = rawData;
+
+    // set the new psImage's deallocator to the same as the input image
+    p_psMemSetDeallocator(out,p_psMemGetDeallocator(image));
+
+    inputColOffset = elementSize * col0;
+    for (int row = 0; row < numRows; row++) {
+        out->data.V[row] = image->data.U8[row0 + row] + inputColOffset;
+    }
+
+    // add output image as a child of the input image.
+    int n = 0;
+    psArray* children = image->children;
+    if (children == NULL) {
+        children = psArrayAlloc(16); // start with a reasonable size for growth
+    } else if (children->nalloc == children->n) { // full?
+        n = children->n;
+        children = psArrayRealloc(children,n*2); // double the array size
+    } else {
+        n = children->n;
+    }
+    children->data[n] = out;
+    children->n = n+1;
+    image->children = children; // push back any change (esp. if children==NULL before)
+
+    return (out);
+}
+
+psImage* psImageSubset(psImage* image,
+                       int col0,
+                       int row0,
+                       int col1,
+                       int row1)
+{
+    return imageSubset(NULL,image,col0,row0,col1,row1);
+}
+
+psImage* psImageSubsection(psImage* image,
+                           const char* section)
+{
+    int col0;
+    int col1;
+    int row0;
+    int row1;
+
+    // section should be of the form '[col0:col1,row0:row1]'
+    if (section == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageSubsection",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_SUBSECTION_NULL);
+        return NULL;
+    }
+
+    if (sscanf(section,"[%d:%d,%d:%d]",&col0,&col1,&row0,&row1) < 4) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageSubsection",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_SUBSECTION_INVALID,
+                   section);
+        return NULL;
+    }
+
+    if (col0 > col1 || row0 > row1) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageSubsection",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImage_SUBSET_RANGE_MALFORMED,
+                   col0,col1,row0,row1);
+        return NULL;
+    }
+
+    return imageSubset(NULL,image,col0,row0,col1+1,row1+1);
+}
+
+psImage* psImageTrim(psImage* image, int col0, int row0, int col1, int row1)
+{
+    if (image == NULL || image->data.V == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageTrim",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        return NULL;
+    }
+
+    if (image->parent != NULL) {
+        return imageSubset(image,
+                           (psImage*)image->parent,
+                           col0+image->col0,
+                           row0+image->row0,
+                           col1+image->col0,
+                           row1+image->row0);
+    }
+
+    if (col1 < 1) {
+        col1 += image->numCols;
+    }
+
+    if (row1 < 1) {
+        row1 += image->numRows;
+    }
+
+    if (    col0 < 0 ||
+            row0 < 0 ||
+            col1 > image->numCols ||
+            row1 > image->numRows ||
+            col0 >= col1 ||
+            row0 >= row1 ) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageTrim",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImage_SUBSET_RANGE_INVALID,
+                   col0, col1-1, row0, row1-1,
+                   image->numCols-1, image->numRows-1);
+        psFree(image);
+        return NULL;
+    }
+
+    psImageFreeChildren(image);
+
+    unsigned int elementSize = PSELEMTYPE_SIZEOF(image->type.type);
+    unsigned int numCols = col1-col0;
+    unsigned int numRows = row1-row0;
+    unsigned int rowSize = elementSize*numCols;
+    unsigned int colOffset = elementSize * col0;
+    psU8* imageData = image->rawDataBuffer;
+    for (int row = row0; row < row1; row++) {
+        memmove(imageData,image->data.U8[row] + colOffset,rowSize);
+        imageData += rowSize;
+    }
+
+    *(unsigned int*)&image->numRows = numRows;
+    *(unsigned int*)&image->numCols = numCols;
+
+    // XXX: should I really resize the buffers?
+    image->data.V = psRealloc(image->data.V,sizeof(void*)*numRows);
+    image->rawDataBuffer = psRealloc(image->rawDataBuffer,rowSize*numRows);
+
+    image->data.V[0] = image->rawDataBuffer;
+    for (int r = 1; r < numRows; r++) {
+        image->data.U8[r] = image->data.U8[r-1] + rowSize;
+    }
+
+    return (image);
+}
+
+psVector* psImageSlice(psVector* out,
+                       psVector* slicePositions,
+                       const psImage* restrict in,
+                       const psImage* restrict mask,
+                       unsigned int maskVal,
+                       int col0,
+                       int row0,
+                       int col1,
+                       int row1,
+                       psImageCutDirection direction,
+                       const psStats* stats)
+{
+    double statVal;
+    psStats* myStats;
+    psElemType type;
+    int inRows;
+    int inCols;
+    int delta = 1;
+    psF64* outData;
+
+    if (in == NULL || in->data.V == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageSlice",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    if (col1 < 1) {
+        col1 += in->numCols;
+    }
+
+    if (row1 < 1) {
+        row1 += in->numRows;
+    }
+
+    if (    col0 < 0 ||
+            row0 < 0 ||
+            col1 > in->numCols ||
+            row1 > in->numRows ||
+            col0 >= col1 ||
+            row0 >= row1) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageSlice",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImage_SUBSET_RANGE_INVALID,
+                   col0, col1, row0, row1,
+                   in->numCols, in->numRows);
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    inRows = in->numRows;
+    inCols = in->numCols;
+
+    if (direction == PS_CUT_X_NEG || direction == PS_CUT_Y_NEG) {
+        delta = -1;
+    }
+
+    if (mask != NULL) {
+        if (inRows != mask->numRows || inCols != mask->numCols) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageSlice",
+                       PS_ERR_BAD_PARAMETER_VALUE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_MASK_SIZE,
+                       mask->numCols,mask->numRows,
+                       inCols, inRows);
+            psFree(out);
+            return NULL;
+        }
+        if (mask->type.type != PS_TYPE_MASK) {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,mask->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageSlice",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE,
+                       typeStr, PS_TYPE_MASK_NAME);
+            psFree(out);
+            return NULL;
+        }
+    }
+
+    if (stats == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageSlice",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_STAT_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    // verify that the stats struct specifies a
+    // single stats operation
+    if (p_psGetStatValue(stats, &statVal) == false) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageSlice",
+                   PS_ERR_BAD_PARAMETER_VALUE, false,
+                   PS_ERRORTEXT_psImage_BAD_STAT,stats->options);
+        psFree(out);
+        return NULL;
+    }
+    // since stats input is const, I need to
+    // create a 'scratch' stats struct
+    myStats = psAlloc(sizeof(psStats));
+    *myStats = *stats;
+
+    int numCols = col1-col0;
+    int numRows = row1-row0;
+
+    if (direction == PS_CUT_X_POS || direction == PS_CUT_X_NEG) {
+        psVector* imgVec = psVectorAlloc(numRows, type);
+        psVector* maskVec = NULL;
+        psMaskType* maskData = NULL;
+        psU32* outPosition = NULL;
+
+        // recycle output to make a proper sized/type output structure
+        // n.b. type is double as that is the type given for all stats is
+        // psStats.
+        out = psVectorRecycle(out, numCols, PS_TYPE_F64);
+        if (slicePositions != NULL) {
+            slicePositions = psVectorRecycle(slicePositions, numCols, PS_TYPE_U32);
+            outPosition = slicePositions->data.U32;
+        }
+        outData = out->data.F64;
+        if (delta < 0) {
+            outData += numCols - 1;
+            if (outPosition != NULL) {
+                outPosition += numCols - 1;
+            }
+        }
+
+        if (mask != NULL) {
+            maskVec = psVectorAlloc(numRows, mask->type.type);
+        }
+        #define PSIMAGE_CUT_VERTICAL(TYPE) \
+    case PS_TYPE_##TYPE: { \
+            psMaskType* maskVecData = NULL; \
+            for (int c=col0;c<col1;c++) { \
+                ps##TYPE *imgData = in->data.TYPE[row0] + c; \
+                ps##TYPE *imgVecData = imgVec->data.TYPE; \
+                if (maskVec != NULL) { \
+                    maskVecData = maskVec->data.V; \
+                    maskData = (psMaskType* )(mask->data.V[row0]) + c; \
+                } \
+                for (int r=row0;r<row1;r++) { \
+                    *(imgVecData++) = *imgData; \
+                    imgData += inCols; \
+                    if (maskVecData != NULL) { \
+                        *(maskVecData++) = *maskData; \
+                        maskData += inCols; \
+                    } \
+                } \
+                myStats = psVectorStats(myStats,imgVec,maskVec,maskVal); \
+                (void)p_psGetStatValue(myStats,&statVal); \
+                *outData = statVal; \
+                if (outPosition != NULL) { \
+                    *outPosition = c; \
+                    outPosition += delta; \
+                } \
+                outData += delta; \
+            } \
+            break; \
+        }
+
+        switch (type) {
+            //            PSIMAGE_CUT_VERTICAL(U8);         Not a requirement
+            PSIMAGE_CUT_VERTICAL(U16);
+            //            PSIMAGE_CUT_VERTICAL(U32);        Not a requirement
+            //            PSIMAGE_CUT_VERTICAL(U64);        Not a requirement
+            PSIMAGE_CUT_VERTICAL(S8);
+            //            PSIMAGE_CUT_VERTICAL(S16);        Not a requirement
+            //            PSIMAGE_CUT_VERTICAL(S32);        Not a requirement
+            //            PSIMAGE_CUT_VERTICAL(S64);        Not a requirement
+            PSIMAGE_CUT_VERTICAL(F32);
+            PSIMAGE_CUT_VERTICAL(F64);
+            //            PSIMAGE_CUT_VERTICAL(C32);        Not a requirement
+            //            PSIMAGE_CUT_VERTICAL(C64);        Not a requirement
+        default: {
+                char* typeStr;
+                PS_TYPE_NAME(typeStr,type);
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageSlice",
+                           PS_ERR_BAD_PARAMETER_TYPE, true,
+                           PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                           typeStr);
+                psFree(out);
+                out = NULL;
+            }
+        }
+        psFree(imgVec);
+        psFree(maskVec);
+    } else if (direction == PS_CUT_Y_POS || direction == PS_CUT_Y_NEG) {
+        // Cut in Y direction
+        psVector* imgVec = NULL;
+        psVector* maskVec = NULL;
+        int elementSize = PSELEMTYPE_SIZEOF(type);
+        psU32* outPosition = NULL;
+
+        // fill in psVector to fake out the statistics functions.
+        imgVec = psAlloc(sizeof(psVector));
+        imgVec->type = in->type;
+        imgVec->n = imgVec->nalloc = numCols;
+        if (mask != NULL) {
+            maskVec = psAlloc(sizeof(psVector));
+            maskVec->type = mask->type;
+            maskVec->n = maskVec->nalloc = numCols;
+        }
+        // recycle output to make a proper sized/type output structure
+        // n.b. type is double as that is the type given for all stats in
+        // psStats.
+        out = psVectorRecycle(out, numRows, PS_TYPE_F64);
+        if (slicePositions != NULL) {
+            slicePositions = psVectorRecycle(slicePositions, numRows, PS_TYPE_U32);
+            outPosition = slicePositions->data.U32;
+        }
+        outData = out->data.F64;
+        if (delta < 0) {
+            outData += numRows-1;
+            if (outPosition != NULL) {
+                outPosition += numRows-1;
+            }
+        }
+
+        for (int r = row0; r < row1; r++) {
+            // point the vector struct to the
+            // data to calculate the stats
+            imgVec->data.V = (void *)(in->data.U8[r] + col0 * elementSize);
+            if (maskVec != NULL) {
+                maskVec->data.V = (void *)(mask->data.U8[r] + col0 * sizeof(psMaskType));
+            }
+            myStats = psVectorStats(myStats, imgVec, maskVec, maskVal);
+            (void)p_psGetStatValue(myStats, &statVal);  // we know it works cause we tested it above
+            *outData = statVal;
+            if (outPosition != NULL) {
+                *outPosition = r;
+                outPosition += delta;
+
+            }
+            outData += delta;
+        }
+        psFree(imgVec);
+        psFree(maskVec);
+    } else { // don't know what the direction flag is
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageSlice",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImage_SLICE_DIRECTION_INVALID,
+                   direction);
+        psFree(out);
+        out = NULL;
+    }
+
+    psFree(myStats);
+
+    return out;
+}
+
+psVector* psImageCut(psVector* out,
+                     psVector* cutCols,
+                     psVector* cutRows,
+                     const psImage* in,
+                     const psImage* restrict mask,
+                     unsigned int maskVal,
+                     float startCol,
+                     float startRow,
+                     float endCol,
+                     float endRow,
+                     unsigned int nSamples,
+                     psImageInterpolateMode mode)
+{
+    if (in == NULL || in->data.V == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCut",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(out);
+        return NULL;
+    }
+    int numCols = in->numCols;
+    int numRows = in->numRows;
+
+    if (nSamples < 2) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCut",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImage_nSamples_TOOSMALL,
+                   nSamples);
+        psFree(out);
+        return NULL;
+    }
+
+    if (startCol < 0 || startCol >= numCols ||
+            startRow < 0 || startRow >= numRows ||
+            endCol < 0 || endCol >= numCols ||
+            endRow < 0 || endRow >= numRows) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCut",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImage_LINE_NOT_IN_IMAGE,
+                   startCol,startRow,endCol,endRow,
+                   numCols-1,numRows-1);
+        psFree(out);
+        return NULL;
+    }
+
+    if (mode < PS_INTERPOLATE_FLAT || mode >= PS_INTERPOLATE_NUM_MODES) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageResample",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImageManip_INTERPOLATION_MODE_UNSUPPORTED,
+                   mode);
+        psFree(out);
+        return NULL;
+    }
+
+    if (mask != NULL) {
+        if (numRows != mask->numRows || numCols != mask->numCols) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCut",
+                       PS_ERR_BAD_PARAMETER_VALUE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_MASK_SIZE,
+                       mask->numCols,mask->numRows,
+                       numCols-1, numRows);
+            psFree(out);
+            return NULL;
+        }
+        if (mask->type.type != PS_TYPE_MASK) {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,mask->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCut",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE,
+                       typeStr, PS_TYPE_MASK_NAME);
+            psFree(out);
+            return NULL;
+        }
+    }
+
+    //resize the vectors for the coordinate output
+    psF32* cutColsData = NULL;
+    psF32* cutRowsData = NULL;
+    if (cutCols != NULL) {
+        (void)psVectorRecycle(cutCols, nSamples, PS_TYPE_F32);
+        cutColsData = cutCols->data.F32;
+    }
+    if (cutRows != NULL) {
+        (void)psVectorRecycle(cutRows, nSamples, PS_TYPE_F32);
+        cutRowsData = cutRows->data.F32;
+    }
+
+    out = psVectorRecycle(out, nSamples, in->type.type);
+
+    float dX = (endCol - startCol) / (float)(nSamples-1);
+    float dY = (endRow - startRow) / (float)(nSamples-1);
+
+    #define LINEAR_CUT_CASE(TYPE) \
+case PS_TYPE_##TYPE: { \
+        ps##TYPE* outData = out->data.TYPE; \
+        for (int i = 0; i < nSamples; i++) { \
+            float x = startCol + (float)i*dX; \
+            float y = startRow + (float)i*dY; \
+            /* store off the location of the sample. */ \
+            if (cutColsData != NULL) { \
+                cutColsData[i] = x; \
+            } \
+            if (cutRowsData != NULL) { \
+                cutRowsData[i] = y; \
+            } \
+            outData[i] = psImagePixelInterpolate(in,x,y,mask,maskVal,0,mode); \
+        } \
+    } \
+    break;
+
+
+    switch (in->type.type) {
+        LINEAR_CUT_CASE(U8);
+        LINEAR_CUT_CASE(U16);
+        LINEAR_CUT_CASE(U32);
+        LINEAR_CUT_CASE(U64);
+        LINEAR_CUT_CASE(S8);
+        LINEAR_CUT_CASE(S16);
+        LINEAR_CUT_CASE(S32);
+        LINEAR_CUT_CASE(S64);
+        LINEAR_CUT_CASE(F32);
+        LINEAR_CUT_CASE(F64);
+        LINEAR_CUT_CASE(C32);
+        LINEAR_CUT_CASE(C64);
+
+    default: {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,in->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCut",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                       typeStr);
+            psFree(out);
+            out = NULL;
+        }
+    }
+
+    return out;
+}
+
+psVector* psImageRadialCut(psVector* out,
+                           const psImage* in,
+                           const psImage* restrict mask,
+                           unsigned int maskVal,
+                           float centerCol,
+                           float centerRow,
+                           const psVector* radii,
+                           const psStats* stats)
+{
+    double statVal;
+
+    /* check the parameters */
+
+    if (in == NULL || in->data.V == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRadialCut",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(out);
+        return NULL;
+    }
+    int numCols = in->numCols;
+    int numRows = in->numRows;
+
+    if (mask != NULL) {
+        if (numRows != mask->numRows || numCols != mask->numCols) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRadialCut",
+                       PS_ERR_BAD_PARAMETER_SIZE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_MASK_SIZE,
+                       mask->numCols,mask->numRows,
+                       numCols, numRows);
+            psFree(out);
+            return NULL;
+        }
+        if (mask->type.type != PS_TYPE_MASK) {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,mask->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRadialCut",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE,
+                       typeStr, PS_TYPE_MASK_NAME);
+            psFree(out);
+            return NULL;
+        }
+    }
+
+    if (centerCol < 0 || centerCol >= numCols ||
+            centerRow < 0 || centerRow >= numRows) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRadialCut",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImage_CENTER_NOT_IN_IMAGE,
+                   centerCol, centerRow,
+                   numCols-1, numRows-1);
+        psFree(out);
+        return NULL;
+    }
+
+    if (radii == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRadialCut",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_RADII_VECTOR_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    if (radii->n < 2) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRadialCut",
+                   PS_ERR_BAD_PARAMETER_SIZE, true,
+                   PS_ERRORTEXT_psImage_RADII_VECTOR_TOOSMALL,
+                   radii->n);
+        psFree(out);
+        return NULL;
+    }
+
+    if (stats == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRadialCut",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_STAT_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    // verify that the stats struct specifies a
+    // single stats operation
+    if (p_psGetStatValue(stats, &statVal) == false) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRadialCut",
+                   PS_ERR_BAD_PARAMETER_VALUE, false,
+                   PS_ERRORTEXT_psImage_BAD_STAT,
+                   stats->options);
+        psFree(out);
+        return NULL;
+    }
+
+    /* completed checking the parameters */
+
+    // size the output vector to proper size.
+    int numOut = radii->n - 1;
+    out = psVectorRecycle(out, numOut, PS_TYPE_F64);
+    psF64* outData = out->data.F64;
+
+    psVector* rSqVec = psVectorCopy(NULL, radii, PS_TYPE_F32);
+    psF32* rSq = rSqVec->data.F32;
+
+    int startRow = centerRow - rSq[numOut];
+    int endRow = centerRow + rSq[numOut];
+    int startCol = centerCol - rSq[numOut];
+    int endCol = centerCol + rSq[numOut];
+
+    if (startRow < 0) {
+        startRow = 0;
+    }
+
+    if (startCol < 0) {
+        startCol = 0;
+    }
+
+    if (endRow >= numRows) {
+        endRow = numRows - 1;
+    }
+
+    if (endCol >= numCols) {
+        endCol = numCols - 1;
+    }
+
+    // Square the radii data
+    for (int d = 0; d <= numOut; d++) {
+        rSq[d] *= rSq[d];
+    }
+
+    // create temporary vectors for the data binning step
+    psVector** buffer = psAlloc(sizeof(psVector*)*numOut);
+    psVector** bufferMask = psAlloc(sizeof(psVector*)*numOut);
+    for (int lcv = 0; lcv < numOut; lcv++) {
+        // n.b. alloc enough for the data by making the vectors slightly larger
+        // than the area of the region of interest.
+        buffer[lcv] = psVectorAlloc(1+4*(rSq[lcv+1]-rSq[lcv]),
+                                    in->type.type);
+        buffer[lcv]->n = 0;
+
+        bufferMask[lcv] = NULL;
+        if (mask != NULL) {
+            bufferMask[lcv] = psVectorAlloc(1+4*(rSq[lcv+1]-rSq[lcv]),
+                                            PS_TYPE_MASK);
+            bufferMask[lcv]->n = 0;
+        }
+    }
+
+    float dX;
+    float dY;
+    float dist;
+    for (int row=startRow; row <= endRow; row++) {
+        psF32* inRow = in->data.F32[row];
+        psMaskType* maskRow = NULL;
+        if (mask != NULL) {
+            maskRow = mask->data.PS_TYPE_MASK_DATA[row];
+        }
+        for (int col=startCol; col <= endCol; col++) {
+            dX = centerCol - (float)col - 0.5f;
+            dY = centerRow - (float)row - 0.5f;
+            dist = dX*dX+dY*dY;
+            for (int r = 0; r < numOut; r++) {
+                if (rSq[r] < dist && dist < rSq[r+1]) {
+                    int n = buffer[r]->n;
+                    if (n == buffer[r]->nalloc) { // in case buffers already full, expand
+                        buffer[r] = psVectorRealloc(buffer[r], n*2);
+                        if (bufferMask[r] != NULL) {
+                            bufferMask[r] = psVectorRealloc(bufferMask[r], n*2);
+                        }
+                    }
+
+                    buffer[r]->data.F32[n] = inRow[col];
+                    buffer[r]->n = n+1;
+
+                    if (maskRow != NULL) {
+                        bufferMask[r]->data.PS_TYPE_MASK_DATA[n] = maskRow[col];
+                        bufferMask[r]->n = n+1;
+                    }
+
+                    break;
+                }
+            }
+        }
+    }
+
+    psStats* myStats = psAlloc(sizeof(psStats));
+    *myStats = *stats;
+
+    for (int r = 0; r < numOut; r++) {
+        myStats = psVectorStats(myStats,buffer[r], bufferMask[r],maskVal);
+        (void)p_psGetStatValue(myStats,&statVal);
+        outData[r] = statVal;
+    }
+
+    psFree(myStats);
+
+    for (int lcv = 0; lcv < numOut; lcv++) {
+        psFree(buffer[lcv]);
+        psFree(bufferMask[lcv]);
+    }
+    psFree(buffer);
+    psFree(bufferMask);
+    psFree(rSqVec);
+    return out;
+}
Index: /branches/rel3/psLib/src/image/psImageExtraction.h
===================================================================
--- /branches/rel3/psLib/src/image/psImageExtraction.h	(revision 2163)
+++ /branches/rel3/psLib/src/image/psImageExtraction.h	(revision 2163)
@@ -0,0 +1,198 @@
+
+/** @file  psImageExtraction.h
+*
+*  @brief Contains basic image extraction operations, as specified in the 
+*         PSLIB SDRS sections "Image Pixel Extractions" and "Image Structure
+*         Manipulation".
+*
+*  @ingroup Image
+*
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-13 22:05:03 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#ifndef PSIMAGEEXTRACTION_H
+#define PSIMAGEEXTRACTION_H
+
+#include "psImage.h"
+#include "psVector.h"
+#include "psStats.h"
+
+/// @addtogroup Image
+/// @{
+
+/* Cut direction flag.  Used with psImageCut function.
+ */
+typedef enum {
+    PS_CUT_X_POS,                      ///< Cut in the x dimension from left to right
+    PS_CUT_X_NEG,                      ///< Cut in the x dimension from rigth to left
+    PS_CUT_Y_POS,                      ///< Cut in the y dimension from bottom up
+    PS_CUT_Y_NEG,                      ///< Cut in the y dimension from top down.
+} psImageCutDirection;
+
+/** Create a subimage of the specified area.
+ *
+ *  Extracts a subimage starting at (col0,row0) to (col1-1,row1-1).  Note: 
+ *  the column col1 and row row1 are NOT included in the resulting subimage.
+ *  In the event that x1 or y1 are non-positive, they shall be interpreted as
+ *  being relative to the size of the parent image in that dimension.
+ *
+ *  If the entire specified subimage is not contained within the parent 
+ *  image, an error results and the return value will be NULL.
+ *
+ *  The resulting psImage does not create a copy of the underlying image 
+ *  data.  Future changes in the parent may be reflecting in the child
+ *  subimage and vis versa.
+ *
+ *  @return psImage* : Pointer to psImage.
+ *
+ */
+psImage* psImageSubset(
+    psImage* image,                    ///< Parent image.
+    int col0,                          ///< starting column of subimage
+    int row0,                          ///< starting row of subimage
+    int col1,                          ///< exclusive end column of subimage.
+    int row1                           ///< exclusive end row of subimage
+);
+
+/** Create a subimage of the specified area.
+ *
+ * Uses psLib memory allocation functions to create an image based on a larger
+ * one.
+ *
+ * @return psImage* : Pointer to psImage.
+ *
+ */
+psImage* psImageSubsection(
+    psImage* image,                    ///< Parent image.
+    const char* section                ///< Subsection in the form '[x1:x2,y1:y2]'
+);
+
+/** Trim an image
+ *
+ *  Trim the specified image in-place, which involves shuffling the pixels 
+ *  around in memory.  The pixels in the region [col0:col1,row0:row1] shall consist
+ *  the output image.  The column col1 and row row1 are NOT included in the range.
+ *  In the event that x1 or y1 are non-positive, they shall be interpreted as
+ *  being relative to the size of the parent image in that dimension.
+ *
+ *  If the entire specified subimage is not contained within the parent 
+ *  image, an error results and the return value will be NULL.
+ *
+ *  N.B. If the input psImage is a child of another psImage, no pixel data 
+ *  will be trimmed, rather it equivalent to calling psImageSubset.  If the input 
+ *  psImage is, however, a parent psImage, any children will be obliterated,
+ *  i.e., freed from memory.
+ *
+ *  @return psImage*  trimmed image result
+ */
+psImage* psImageTrim(
+    psImage* image,                    ///< image to trim
+    int col0,                          ///< column of trim region's left boundary
+    int row0,                          ///< row of trim region's lower boundary
+    int col1,                          ///< column of trim region's right boundary
+    int row1                           ///< row of trim region's upper boundary
+);
+
+/** Extract pixels from rectlinear region to a vector (array of floats).
+ *
+ *  The output vector contains either col1-col0 or row1-row0 elements, based 
+ *  on the value of the direction: e.g., if direction is PS_CUT_X_POS, there 
+ *  are col1-col0 elements. The region to be  sliced  is defined by the 
+ *  lower-left corner, (col0,row0), and the upper-right corner, (col1,row1). 
+ *  Note that the row and column of the  upper right-hand corner  are NOT 
+ *  included in the region. In the event that col1 or row1 are negative, they
+ *  shall be interpreted as being relative to the size of the parent image in 
+ *  that dimension. The input region is collapsed in the direction perpendicular 
+ *  to that specified by direction, and each element of the output vectors is 
+ *  derived from the statistics of the pixels at that direction coordinate. The
+ *  statistic used to derive the output vector value is specified by stats. 
+ *  If mask is non-NULL, pixels for which the corresponding mask pixel 
+ *  matches maskVal are excluded from operations. If coords is not NULL, the 
+ *  calculated coordinates along the slice are returned in this vector. Only 
+ *  one of the statistics choices may be specified, otherwise the function 
+ *  must return an error.
+ *
+ *  This function is defined for the following types: psS8, psU16, psF32, psF64.
+ *
+ * @return psVector    the resulting vector
+ */
+psVector* psImageSlice(
+    psVector* out,                     ///< psVector to recycle, or NULL.
+    psVector* slicePositions,
+    ///< If not NULL, it is populated with the coordinate in the slice dimension
+    ///< coorsponding to the output vector's value of the same position in the
+    ///< vector.  This vector maybe resized and retyped as appropriate.
+    const psImage* restrict input,     ///< the input image in which to perform the slice
+    const psImage* restrict mask,      ///< the mask for the input image.
+    unsigned int maskVal,              ///< the mask value to apply to the mask
+    int col0,                          ///< the leftmost column of the slice region
+    int row0,                          ///< the bottommost row of the slice region
+    int col1,                          ///< exclusive end column of the slice region
+    int row1,                           ///< exclusive end row of the slice region
+    psImageCutDirection direction,     ///< the slice dimension and direction
+    const psStats* stats               ///< the statistic to perform in slice operation
+);
+
+/** Extract pixels from an image along a line to a vector (array of floats).
+ *
+ *  The vector (xs,ys) - (xe,ye) forms the basis of the output vector. Pixels 
+ *  are considered in a rectangular region of width dw about this vector. The 
+ *  input region is collapsed in the perpendicular direction, and each element 
+ *  of the output vector represents pixel-sized boxes, where the value is 
+ *  derived from the statistics of the pixels interpolated along the 
+ *  perpendicular direction. The specific algorithm which must be used is 
+ *  described in the PSLib ADD (PSDC-430-006). The statistic used to derive 
+ *  the output vector value is specified by stats. Only one of the statistics 
+ *  choices may be specified, otherwise the function must return an error. 
+ *  This function must be defined for the following types: psS8, psU16, psF32, 
+ *  psF64.
+ *
+ *  @return psVector    resulting vector
+ */
+psVector* psImageCut(
+    psVector* out,                     ///< psVector to recycle, or NULL.
+    psVector* cutCols,                 ///< if not NULL, the calculated column values along the slice (output)
+    psVector* cutRows,                 ///< if not NULL, the calculated row values along the slice (output)
+    const psImage* input,              ///< the input image in which to perform the cut
+    const psImage* restrict mask,      ///< the mask for the input image.
+    unsigned int maskVal,              ///< the mask value to apply to the mask
+    float startCol,                    ///< the column of the start of the cut line
+    float startRow,                    ///< the row of the start of the cut line
+    float endCol,                      ///< the column of the end of the cut line
+    float endRow,                      ///< the row of the end of the cut line
+    unsigned int nSamples,             ///< the number of samples along the cut
+    psImageInterpolateMode mode        ///< the interpolation method to use
+);
+
+/** Extract radial region data to a vector. A vector is constructed where each
+ *  vector elements is derived from the statistics of the pixels which land 
+ *  within one of a sequence of radii. The radii are centered on the image 
+ *  pixel coordinate x,y, and are defined by the sequence of values in the
+ *  vector radii. The specific algorithm which must be used is described in 
+ *  the PSLib ADD (PSDC-430-006). The statistic used to derive the output 
+ *  vector value is specified by stats. Only one of the statistics choices 
+ *  may be specified, otherwise the function must return an error. This 
+ *  function must be defined for the following types: psS8, psU16, psF32, 
+ *  psF64.
+ *
+ *  @return psVector    resulting vector
+ */
+psVector* psImageRadialCut(
+    psVector* out,                     ///< psVector to recycle, or NULL.
+    const psImage* input,              ///< the input image in which to perform the cut
+    const psImage* restrict mask,      ///< the mask for the input image.
+    unsigned int maskVal,              ///< the mask value to apply to the mask
+    float centerCol,                   ///< the column of the center of the cut circle
+    float centerRow,                   ///< the row of the center of the cut circle
+    const psVector* radii,             ///< the radii of the cut circle
+    const psStats* stats               ///< the statistic to perform in operation
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/image/psImageFFT.c
===================================================================
--- /branches/rel3/psLib/src/image/psImageFFT.c	(revision 2163)
+++ /branches/rel3/psLib/src/image/psImageFFT.c	(revision 2163)
@@ -0,0 +1,447 @@
+/** @file  psImageFFT.c
+ *
+ *  @brief Contains FFT transform related functions for psImage.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-06 21:31:30 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#include <unistd.h>
+#include <stdbool.h>
+#include <string.h>
+#include <complex.h>
+#include <fftw3.h>
+
+#include "psImageFFT.h"
+#include "psError.h"
+#include "psMemory.h"
+#include "psLogMsg.h"
+#include "psImageExtraction.h"
+#include "psImageIO.h"
+
+#include "psImageErrors.h"
+
+#define PS_FFTW_PLAN_RIGOR FFTW_ESTIMATE
+
+static bool p_fftwWisdomImported = false;
+
+psImage* psImageFFT(psImage* out, const psImage* in, psFftDirection direction)
+{
+    unsigned int numCols;
+    unsigned int numRows;
+    psElemType type;
+    fftwf_plan plan;
+
+    /* got good image data? */
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    if ( ((direction & PS_FFT_FORWARD) != 0) ) {
+        if ((direction & PS_FFT_REVERSE) != 0) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageFFT",
+                       PS_ERR_BAD_PARAMETER_VALUE, true,
+                       PS_ERRORTEXT_psImageFFT_FORWARD_REVERSE);
+            psFree(out);
+            return NULL;
+        }
+        if ((direction & PS_FFT_REAL_RESULT) != 0) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageFFT",
+                       PS_ERR_BAD_PARAMETER_VALUE, true,
+                       PS_ERRORTEXT_psImageFFT_REAL_FORWARD_NOTSUPPORTED);
+            psFree(out);
+            return NULL;
+        }
+    } else if ((direction & PS_FFT_REVERSE) == 0) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageFFT",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImageFFT_NO_DIRECTION_OPTION);
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+
+    /* make sure the system-level wisdom information is imported. */
+    if (!p_fftwWisdomImported) {
+        fftwf_import_system_wisdom();
+        p_fftwWisdomImported = true;
+    }
+
+    numRows = in->numRows;
+    numCols = in->numCols;
+
+    // n.b. FFTW can perform a in-place transform at the same rate or faster than out-of-place.
+    int sign = ((direction & PS_FFT_FORWARD) != 0) ? FFTW_FORWARD : FFTW_BACKWARD;
+    out = psImageCopy(out, in, PS_TYPE_C32);
+    plan = fftwf_plan_dft_2d(numCols, numRows,
+                             out->data.C32[0],
+                             out->data.C32[0],
+                             sign,
+                             PS_FFTW_PLAN_RIGOR);
+
+    /* check if a plan exists now -- if not, it is a real problem at this point */
+    if (plan == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageFFT",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImageFFT_FFTW_PLAN_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    /* finally, call FFTW with the plan made above */
+    fftwf_execute(plan);
+
+    fftwf_destroy_plan(plan);
+
+    if (direction & PS_FFT_REAL_RESULT) {
+        // n.b., we do this instead of using fftwf_plan_dft_c2r because that
+        // plan requires a half-image, which would require a image reordering
+        // that is not as simple as performing a normal complex transform and
+        // then taking the real part of the result.  If performance here
+        // becomes an issue, the use of fftwf_plan_dft_r2c should be considered
+        // as well as fftwf_plan_dft_c2r.
+        psImage* realOut = psImageCopy(NULL,out,PS_TYPE_F32);
+        psFree(out);
+        out = realOut;
+    }
+
+    return out;
+
+}
+
+psImage* psImageReal(psImage* out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+
+    /* if not a complex number, this is logically just a copy then */
+    if (!PS_IS_PSELEMTYPE_COMPLEX(type) && type != PS_TYPE_PTR) {
+        return psImageCopy(out, in, type);
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outRow;
+        psC32* inRow;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_F32);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                outRow[col] = crealf(inRow[col]);
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outRow;
+        psC64* inRow;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_F64);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                outRow[col] = creal(inRow[col]);
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageReal",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                   typeStr);
+
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage* psImageImaginary(psImage* out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+
+    /* if not a complex image type, this is logically just zeroed image of same size */
+    if (!PS_IS_PSELEMTYPE_COMPLEX(type) && type != PS_TYPE_PTR) {
+        out = psImageRecycle(out, numCols, numRows, type);
+        memset(out->data.V[0], 0, PSELEMTYPE_SIZEOF(type) * numCols * numRows);
+        return out;
+    }
+
+    if (type == PS_TYPE_C32) {
+        psF32* outRow;
+        psC32* inRow;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_F32);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                outRow[col] = cimagf(inRow[col]);
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outRow;
+        psC64* inRow;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_F64);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                outRow[col] = cimag(inRow[col]);
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageImaginary",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage* psImageComplex(psImage* out, const psImage* real, const psImage* imag)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+    if (real == NULL || imag == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = real->type.type;
+    numCols = real->numCols;
+    numRows = real->numRows;
+
+    if (imag->type.type != type) {
+        char* typeStrReal;
+        char* typeStrImag;
+        PS_TYPE_NAME(typeStrReal,type);
+        PS_TYPE_NAME(typeStrImag,imag->type.type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageComplex",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImageFFT_REAL_IMAG_TYPE_MISMATCH,
+                   typeStrReal,typeStrImag);
+        psFree(out);
+        return NULL;
+    }
+
+    if (imag->numCols != numCols || imag->numRows != numRows) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageComplex",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImageFFT_REAL_IMAG_SIZE_MISMATCH,
+                   numCols, numRows, imag->numCols, imag->numRows);
+        psFree(out);
+        return NULL;
+    }
+
+    if (type == PS_TYPE_F32) {
+        psC32* outRow;
+        psF32* realRow;
+        psF32* imagRow;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_C32);
+
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.C32[row];
+            realRow = real->data.F32[row];
+            imagRow = imag->data.F32[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                outRow[col] = realRow[col] + I * imagRow[col];
+            }
+        }
+    } else if (type == PS_TYPE_F64) {
+        psC64* outRow;
+        psF64* realRow;
+        psF64* imagRow;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_C64);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.C64[row];
+            realRow = real->data.F64[row];
+            imagRow = imag->data.F64[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                outRow[col] = realRow[col] + I * imagRow[col];
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageComplex",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImageFFT_NONREAL_NOTSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+
+    return out;
+}
+
+psImage* psImageConjugate(psImage* out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+
+    /* if not a complex image, this is logically just a image copy */
+    if (!PS_IS_PSELEMTYPE_COMPLEX(type) && type != PS_TYPE_PTR) {
+        return psImageCopy(out, in, type);
+    }
+
+    if (type == PS_TYPE_C32) {
+        psC32* outRow;
+        psC32* inRow;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_C32);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.C32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                outRow[col] = crealf(inRow[col]) - I * cimagf(inRow[col]);
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psC64* outRow;
+        psC64* inRow;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_C64);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.C64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                outRow[col] = creal(inRow[col]) - I * cimag(inRow[col]);
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageConjugate",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImageFFT_NONCOMPLEX_NOTSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+}
+
+psImage* psImagePowerSpectrum(psImage* out, const psImage* in)
+{
+    psElemType type;
+    unsigned int numCols;
+    unsigned int numRows;
+    int numElementsSquared;
+
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    type = in->type.type;
+    numCols = in->numCols;
+    numRows = in->numRows;
+    numElementsSquared = numCols * numCols * numRows * numRows;
+
+    if (type == PS_TYPE_C32) {
+        psF32* outRow;
+        psC32* inRow;
+        psF32 real;
+        psF32 imag;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_F32);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.F32[row];
+            inRow = in->data.C32[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                real = crealf(inRow[col]);
+                imag = cimagf(inRow[col]);
+                outRow[col] = (real * real + imag * imag) / numElementsSquared;
+            }
+        }
+    } else if (type == PS_TYPE_C64) {
+        psF64* outRow;
+        psC64* inRow;
+        psF64 real;
+        psF64 imag;
+
+        out = psImageRecycle(out, numCols, numRows, PS_TYPE_F64);
+        for (unsigned int row = 0; row < numRows; row++) {
+            outRow = out->data.F64[row];
+            inRow = in->data.C64[row];
+
+            for (unsigned int col = 0; col < numCols; col++) {
+                real = creal(inRow[col]);
+                imag = cimag(inRow[col]);
+                outRow[col] = (real * real + imag * imag) / numElementsSquared;
+            }
+        }
+    } else {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImagePowerSpectrum",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImageFFT_NONCOMPLEX_NOTSUPPORTED,
+                   typeStr);
+        psFree(out);
+        return NULL;
+    }
+
+    return out;
+
+}
Index: /branches/rel3/psLib/src/image/psImageFFT.h
===================================================================
--- /branches/rel3/psLib/src/image/psImageFFT.h	(revision 2163)
+++ /branches/rel3/psLib/src/image/psImageFFT.h	(revision 2163)
@@ -0,0 +1,87 @@
+/** @file  psImageFFT.h
+ *
+ *  @brief Contains FFT transform related functions for psImage
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-25 21:10:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_IMAGE_FFT_H
+#define PS_IMAGE_FFT_H
+
+#include "psImage.h"
+#include "psVectorFFT.h"               // for psFftDirection
+
+/// @addtogroup Transform
+/// @{
+
+/** Forward and reverse FFT calculations.
+ *
+ *  This takes as input the image of interest (in) and the direction 
+ *  (direction), which is specified by an enumerated type psFftDirection.
+ *  The input image may be of type psF32 or psC32, the result is always 
+ *  psC32. If the input vector is psF32, the direction must be forward. 
+ *  
+ *  @return psImage* the FFT transformation result
+ */
+psImage* psImageFFT(
+    psImage* out,                      ///< a psImage to recycle.  If NULL, a new psImage is made.
+    const psImage* in,                 ///< the psImage to apply transform to
+    psFftDirection direction           ///< the direction of the transform
+);
+
+/** extract the real portion of a complex image
+ * 
+ *  @return psImage*   real portion of the input image.
+ */
+psImage* psImageReal(
+    psImage* out,                      ///< a psImage to recycle.  If NULL, a new psImage is made.
+    const psImage* in                  ///< the psImage to extract real portion from
+);
+
+/** extract the imaginary portion of a complex image
+ * 
+ *  @return psImage*   imaginary portion of the input image.
+ */
+psImage* psImageImaginary(
+    psImage* out,                      ///< a psImage to recycle.  If NULL, a new psImage is made.
+    const psImage* in                  ///< the psImage to extract imaginary portion from
+);
+
+/** creates a complex image from separate real and imaginary plane images
+ * 
+ *  @return psImage*   resulting complex image
+ */
+psImage* psImageComplex(
+    psImage* out,                      ///< a psImage to recycle.  If NULL, a new psImage is made.
+    const psImage* real,               ///< the real plane image
+    const psImage* imag                ///< the imaginary plane image
+);
+
+/** computes the complex conjugate of an image
+ * 
+ *  @return psImage*   the complex conjugate of the 'in' image
+ */
+psImage* psImageConjugate(
+    psImage* out,                      ///< a psImage to recycle.  If NULL, a new psImage is made.
+    const psImage* in                  ///< the psImage to compute conjugate of
+);
+
+/** computes the power spectrum of an image
+ * 
+ *  @return psImage*   the power spectrum of the 'in' image
+ */
+psImage* psImagePowerSpectrum(
+    psImage* out,                       ///< a psImage to recycle.  If NULL, a new psImage is made.
+    const psImage* in                   ///< the psImage to power spectrum of
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/image/psImageIO.c
===================================================================
--- /branches/rel3/psLib/src/image/psImageIO.c	(revision 2163)
+++ /branches/rel3/psLib/src/image/psImageIO.c	(revision 2163)
@@ -0,0 +1,438 @@
+/** @file  psImageIO.c
+ *
+ *  @brief Contains image I/O routines.
+ *
+ *  This file defines the file input/output functions for the psImage structure.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-02 02:08:00 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <fitsio.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include "psImageIO.h"
+#include "psError.h"
+#include "psMemory.h"
+
+#include "psImageErrors.h"
+
+psImage* psImageReadSection(psImage* output,
+                            int col,
+                            int row,
+                            int numCols,
+                            int numRows,
+                            int z,
+                            char *extname,
+                            int extnum,
+                            char *filename)
+{
+    fitsfile *fptr = NULL;      /* Pointer to the FITS file */
+    int status = 0;             /* CFITSIO file vars */
+    int nAxis = 0;
+    int anynull = 0;
+    int bitPix = 0;             /* Pixel type */
+    long nAxes[3];
+    long firstPixel[3];         /* lower-left corner of image subset */
+    long lastPixel[3];          /* upper-right corner of image subset */
+    long increment[3];          /* increment for image subset */
+    char fitsErr[80] = "";      /* CFITSIO error message string */
+    int hduType = IMAGE_HDU;
+    int fitsDatatype = 0;
+    int datatype = 0;
+
+    if (filename == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageReadSection",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImageIO_FILENAME_NULL);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Open the FITS file */
+    (void)fits_open_file(&fptr, filename, READONLY, &status);
+    if (fptr == NULL || status != 0) {
+        fits_get_errstatus(status, fitsErr);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageReadSection",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImageIO_FILENAME_INVALID,
+                   filename, fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    /* find the specified extension */
+    if (extname != NULL) {
+        if (fits_movnam_hdu(fptr, hduType, extname, 0, &status) != 0) {
+            fits_get_errstatus(status, fitsErr);
+            status = 0;
+            (void)fits_close_file(fptr, &status);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageReadSection",
+                       PS_ERR_LOCATION_INVALID, true,
+                       PS_ERRORTEXT_psImageIO_EXTNAME_INVALID,
+                       extname, filename, fitsErr);
+            psFree(output);
+            return NULL;
+        }
+    } else {
+        if (fits_movabs_hdu(fptr, extnum + 1, &hduType, &status) != 0) {
+            fits_get_errstatus(status, fitsErr);
+            status = 0;
+            (void)fits_close_file(fptr, &status);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageReadSection",
+                       PS_ERR_LOCATION_INVALID, true,
+                       PS_ERRORTEXT_psImageIO_EXTNUM_INVALID,
+                       extnum, filename, fitsErr);
+            psFree(output);
+            return NULL;
+        }
+    }
+
+    /* Get the data type 'bitPix' from the FITS image */
+    if (fits_get_img_equivtype(fptr, &bitPix, &status) != 0) {
+        fits_get_errstatus(status, fitsErr);
+        status = 0;
+        (void)fits_close_file(fptr, &status);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageReadSection",
+                   PS_ERR_IO, true,
+                   PS_ERRORTEXT_psImageIO_DATATYPE_UNKNOWN,
+                   filename, fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Get the dimensions 'nAxis' from the FITS image */
+    if (fits_get_img_dim(fptr, &nAxis, &status) != 0) {
+        (void)fits_get_errstatus(status, fitsErr);
+        status = 0;
+        (void)fits_close_file(fptr, &status);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageReadSection",
+                   PS_ERR_IO, true,
+                   PS_ERRORTEXT_psImageIO_IMAGE_DIM_UNKNOWN,
+                   filename, fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Validate the number of axis */
+    if ((nAxis < 2) || (nAxis > 3)) {
+        status = 0;
+        (void)fits_close_file(fptr, &status);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageReadSection",
+                   PS_ERR_IO, true,
+                   PS_ERRORTEXT_psImageIO_IMAGE_DIMENSION_UNSUPPORTED,
+                   nAxis);
+        psFree(output);
+        return NULL;
+    }
+
+    /* Get the Image size from the FITS file */
+    if (fits_get_img_size(fptr, nAxis, nAxes, &status) != 0) {
+        (void)fits_get_errstatus(status, fitsErr);
+        status = 0;
+        (void)fits_close_file(fptr, &status);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageReadSection",
+                   PS_ERR_IO, true,
+                   PS_ERRORTEXT_psImageIO_IMAGE_SIZE_UNKNOWN,
+                   filename, fitsErr);
+        psFree(output);
+        return NULL;
+    }
+
+    if (numCols < 1) {
+        numCols += nAxes[0] - col;
+    }
+    if (numRows < 1) {
+        numRows += nAxes[1] - row;
+    }
+
+    firstPixel[0] = col + 1;
+    firstPixel[1] = row + 1;
+    firstPixel[2] = z + 1;
+
+    lastPixel[0] = firstPixel[0] + numCols - 1;
+    lastPixel[1] = firstPixel[1] + numRows - 1;
+    lastPixel[2] = z + 1;
+
+    increment[0] = 1;
+    increment[1] = 1;
+    increment[2] = 1;
+
+    switch (bitPix) {
+    case BYTE_IMG:
+        datatype = PS_TYPE_U8;
+        fitsDatatype = TBYTE;
+        break;
+        /*    case SBYTE_IMG:                  Not a requirement
+                datatype = PS_TYPE_S8;
+                fitsDatatype = TSBYTE;
+                break;     */
+        /*    case USHORT_IMG:                 Not a requirement
+                datatype = PS_TYPE_U16;
+                fitsDatatype = TUSHORT;
+                break;     */
+    case SHORT_IMG:
+        datatype = PS_TYPE_S16;
+        fitsDatatype = TSHORT;
+        break;
+        /*    case ULONG_IMG:                  Not a requirement
+                datatype = PS_TYPE_U32;
+                fitsDatatype = TUINT;
+                break;    */
+    case LONG_IMG:
+        datatype = PS_TYPE_S32;
+        fitsDatatype = TINT;
+        break;
+        /*    case LONGLONG_IMG:               Not a requirement
+                datatype = PS_TYPE_S64;
+                fitsDatatype = TLONGLONG;
+                break;    */
+    case FLOAT_IMG:
+        datatype = PS_TYPE_F32;
+        fitsDatatype = TFLOAT;
+        break;
+    case DOUBLE_IMG:
+        datatype = PS_TYPE_F64;
+        fitsDatatype = TDOUBLE;
+        break;
+    default:
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageReadSection",
+                   PS_ERR_IO, true,
+                   PS_ERRORTEXT_psImageIO_FITS_TYPE_UNSUPPORTED,
+                   bitPix, filename);
+        psFree(output);
+        return NULL;
+    }
+    output = psImageRecycle(output, numCols, numRows, datatype);
+    if (fits_read_subset(fptr, fitsDatatype, firstPixel, lastPixel, increment,
+                         NULL, output->data.V[0], &anynull, &status) != 0) {
+        psFree(output);
+        (void)fits_get_errstatus(status, fitsErr);
+        status = 0;
+        (void)fits_close_file(fptr, &status);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageReadSection",
+                   PS_ERR_IO, true,
+                   PS_ERRORTEXT_psImageIO_READ_FAILED,
+                   filename, fitsErr);
+        return NULL;
+    }
+
+    (void)fits_close_file(fptr, &status);
+
+    return output;
+}
+
+bool psImageWriteSection(psImage* input,
+                         int col0,
+                         int row0,
+                         int z,
+                         char *extname,
+                         int extnum,
+                         char *filename)
+{
+    int numCols = 0;
+    int numRows = 0;
+
+    int status = 0;             /* CFITSIO status */
+    fitsfile *fptr = NULL;      /* pointer to the FITS file */
+    long nAxes[3];              /* Image axis vars */
+    long firstPixel[3];         /* First Pixel to read */
+    long lastPixel[3];          /* Last Pixel to read */
+    char fitsErr[80];           /* FITSIO message string */
+    int datatype = 0;           /* the datatype of the image */
+    int bitPix = 0;             /* FITS bitPix value */
+    int hduType = IMAGE_HDU;    /* the HDU type (image,table, etc.) */
+    double bscale = 1.0;
+    double bzero = 0.0;
+    bool createNewHDU = false;
+
+    /* need a valid image to write */
+    if (input == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageWriteSection",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        return false;
+    }
+
+    numRows = input->numRows;
+    numCols = input->numCols;
+
+    switch (input->type.type) {
+    case PS_TYPE_U8:
+        bitPix = BYTE_IMG;
+        datatype = TBYTE;
+        break;
+        /*    case PS_TYPE_S8:            Not a requirement
+                bitPix = BYTE_IMG;
+                bzero = INT8_MIN;
+                datatype = TSBYTE;
+                break;      */
+        /*    case PS_TYPE_U16:           Not a requirement
+                bitPix = SHORT_IMG;
+                bzero = -1.0f * INT16_MIN;
+                datatype = TUSHORT;
+                break;      */
+    case PS_TYPE_S16:
+        bitPix = SHORT_IMG;
+        datatype = TSHORT;
+        break;
+        /*    case PS_TYPE_U32:           Not a requirement
+                bitPix = LONG_IMG;
+                bzero = -1.0f * INT32_MIN;
+                datatype = TUINT;
+                break;      */
+    case PS_TYPE_S32:
+        bitPix = LONG_IMG;
+        datatype = TINT;
+        break;
+    case PS_TYPE_F32:
+        bitPix = FLOAT_IMG;
+        datatype = TFLOAT;
+        break;
+    case PS_TYPE_F64:
+        bitPix = DOUBLE_IMG;
+        datatype = TDOUBLE;
+        break;
+    default: {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,input->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageWriteSection",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImageIO_TYPE_UNSUPPORTED,
+                       typeStr);
+            return false;
+        }
+    }
+
+    /* Open the FITS file */
+    if (access(filename, F_OK) == 0) {     // file
+        // exists
+        (void)fits_open_file(&fptr, filename, READWRITE, &status);
+        if (fptr == NULL || status != 0) {
+            fits_get_errstatus(status, fitsErr);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageWriteSection",
+                       PS_ERR_BAD_PARAMETER_VALUE, true,
+                       PS_ERRORTEXT_psImageIO_FILENAME_INVALID,
+                       filename, fitsErr);
+            return false;
+        }
+
+        /* find the specified extension */
+        if (extname != NULL) {
+            if (fits_movnam_hdu(fptr, hduType, extname, 0, &status) != 0) {
+                fits_get_errstatus(status, fitsErr);
+                status = 0;
+                (void)fits_close_file(fptr, &status);
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageWriteSection",
+                           PS_ERR_LOCATION_INVALID, true,
+                           PS_ERRORTEXT_psImageIO_EXTNAME_INVALID,
+                           extname, filename, fitsErr);
+                return false;
+            }
+        } else {
+            int numHDUs = 0;
+
+            fits_get_num_hdus(fptr, &numHDUs, &status);
+            if (numHDUs < extnum) {
+                status = 0;
+                (void)fits_close_file(fptr, &status);
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageWriteSection",
+                           PS_ERR_LOCATION_INVALID, true,
+                           PS_ERRORTEXT_psImageIO_WRITE_EXTNUM_INVALID,
+                           extnum, numHDUs);
+                return false;
+            } else if (numHDUs == extnum) {
+                createNewHDU = true;
+            } else if (fits_movabs_hdu(fptr, extnum + 1, &hduType, &status) != 0) {
+                fits_get_errstatus(status, fitsErr);
+                status = 0;
+                (void)fits_close_file(fptr, &status);
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageWriteSection",
+                           PS_ERR_LOCATION_INVALID, true,
+                           PS_ERRORTEXT_psImageIO_EXTNUM_INVALID,
+                           extnum, filename, fitsErr);
+                return false;
+            }
+        }
+
+    } else {                               // file
+        // does
+        // not
+        // exist
+
+        (void)fits_create_file(&fptr, filename, &status);
+        if (fptr == NULL || status != 0) {
+            fits_get_errstatus(status, fitsErr);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageWriteSection",
+                       PS_ERR_IO, true,
+                       PS_ERRORTEXT_psImageIO_FILENAME_CREATE_FAILED,
+                       filename, fitsErr);
+            return false;
+        }
+        createNewHDU = true;
+    }
+
+    if (createNewHDU) {
+        /* create the mandatory image keywords */
+        nAxes[0] = col0 + numCols;
+        nAxes[1] = row0 + numRows;
+        nAxes[2] = z + 1;
+        if (fits_create_img(fptr, bitPix, 3, nAxes, &status) != 0) {
+            (void)fits_get_errstatus(status, fitsErr);
+            status = 0;
+            (void)fits_close_file(fptr, &status);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageWriteSection",
+                       PS_ERR_IO, true,
+                       PS_ERRORTEXT_psImageIO_CREATE_HDU_FAILED,
+                       filename, fitsErr);
+            return false;
+        }
+        // set the bscale/bzero
+        fits_write_key_dbl(fptr, "BZERO", bzero, 12, "Pixel Value Offset", &status);
+        fits_write_key_dbl(fptr, "BSCALE", bscale, 12, "Pixel Value Scale", &status);
+        fits_set_bscale(fptr, bscale, bzero, &status);
+
+        if (extname != NULL) {
+            /* create the extension for the Primary HDU */
+            if (fits_write_key_str(fptr, "EXTNAME", extname, "Extension Name", &status) != 0) {
+                (void)fits_get_errstatus(status, fitsErr);
+                status = 0;
+                (void)fits_close_file(fptr, &status);
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageWriteSection",
+                           PS_ERR_IO, true,
+                           PS_ERRORTEXT_psImageIO_CREATE_EXTENSION_FAILED,
+                           filename, fitsErr);
+                return false;
+            }
+        }
+    }
+
+    firstPixel[0] = col0 + 1;
+    firstPixel[1] = row0 + 1;
+    firstPixel[2] = z + 1;
+
+    lastPixel[0] = firstPixel[0] + numCols - 1;
+    lastPixel[1] = firstPixel[1] + numRows - 1;
+    lastPixel[2] = z + 1;
+
+    if (fits_write_subset(fptr, datatype, firstPixel, lastPixel, input->data.V[0], &status) != 0) {
+        (void)fits_get_errstatus(status, fitsErr);
+        status = 0;
+        (void)fits_close_file(fptr, &status);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageWriteSection",
+                   PS_ERR_IO, true,
+                   PS_ERRORTEXT_psImageIO_WRITE_FAILED,
+                   filename, fitsErr);
+        return false;
+    }
+
+    status = 0;
+    (void)fits_close_file(fptr, &status);
+
+    return true;
+}
Index: /branches/rel3/psLib/src/image/psImageIO.h
===================================================================
--- /branches/rel3/psLib/src/image/psImageIO.h	(revision 2163)
+++ /branches/rel3/psLib/src/image/psImageIO.h	(revision 2163)
@@ -0,0 +1,98 @@
+
+/** @file  psImageIO.h
+ *
+ *  @brief Contains image input/output routines
+ *
+ *  This file defines the file input/output functions for the psImage structure.
+ *
+ *  @ingroup ImageIO
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-10 01:05:53 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#ifndef PS_IMAGEIO_H
+#define PS_IMAGEIO_H
+
+#include <stdbool.h>
+
+#include "psImage.h"
+
+/// @addtogroup ImageIO
+/// @{
+
+/** Read an image or subimage from a FITS file specified by a filename.
+ *
+ *  return psImage* The image read from the specified file.  NULL
+ *                          signifies that a problem had occured.
+ */
+psImage* psImageReadSection(
+    psImage* output,
+    /**< the output psImage to recycle, or NULL if new psImage desired */
+
+    int col0,
+    /**< the column index of the origin to start reading */
+
+    int row0,
+    /**< the row index of the origin to start reading */
+
+    int numCols,
+    /**< the number of desired columns to read */
+
+    int numRows,
+    /**< the number of desired rows to read */
+
+    int z,
+    /**< the z index to read if file is organized as a 3D image cube. */
+
+    char *extname,
+    /**< the image extension to read (this should match the EXTNAME keyword in
+        *   the extension If NULL, the extnum parameter is to be used instead
+        */
+
+    int extnum,
+    /**< the image extension to read (0=PHU, 1=first extension, etc.)  This is
+        *   only used if extname is NULL
+        */
+
+    char *filename
+    /**< the filename of the FITS image file to read */
+);
+
+/** Read an image or subimage from a FITS file specified by a filename.
+ *
+ *  return bool         TRUE is successful, otherwise FALSE.
+ */
+bool psImageWriteSection(
+    psImage* input,
+    /**< the psImage to write */
+
+    int col0,
+    /**< the column index of the origin to start writing */
+
+    int row0,
+    /**< the row index of the origin to start writing */
+
+    int z,
+    /**< the z index to start writing */
+
+    char *extname,
+    /**< the image extension to write (this should match the EXTNAME keyword in
+    *   the extension If NULL, the extnum parameter is to be used instead
+    */
+
+    int extnum,
+    /**< the image extension to write (0=PHU, 1=first extension, etc.)  This is
+    *   only used if extname is NULL.
+    */
+
+    char *filename
+    /**< the filename of the FITS image file to write */
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/image/psImageManip.c
===================================================================
--- /branches/rel3/psLib/src/image/psImageManip.c	(revision 2163)
+++ /branches/rel3/psLib/src/image/psImageManip.c	(revision 2163)
@@ -0,0 +1,1085 @@
+/** @file  psImageManip.c
+ *
+ *  @brief Contains basic image pixel and geometry manipulation operations, as
+ *         specified in the PSLIB SDRS sections "Image Pixel Manipulations" and
+ *         "Image Geometry Manipulations".
+ *
+ *  @ingroup Image
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.28 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 01:22:59 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <math.h>                          // for isfinite(), etc.
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>                        // for memcpy, etc.
+
+#include "psError.h"
+#include "psImage.h"
+#include "psStats.h"
+#include "psMemory.h"
+#include "psImageExtraction.h"
+
+#include "psImageErrors.h"
+
+int psImageClip(psImage* input,
+                psF64 min,
+                psF64 vmin,
+                psF64 max,
+                psF64 vmax)
+{
+    int numClipped = 0;
+    unsigned int numRows;
+    unsigned int numCols;
+
+    if (input == NULL) {
+        return 0;
+    }
+
+    if (max < min) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageClip",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImageManip_MAXMIN,
+                   (double)min,(double)max);
+        return 0;
+    }
+
+    numRows = input->numRows;
+    numCols = input->numCols;
+
+    switch (input->type.type) {
+
+        #define psImageClipCase(type) \
+    case PS_TYPE_##type: { \
+            if (vmin < PS_MIN_##type || vmin > PS_MAX_##type) { \
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageClip", \
+                           PS_ERR_BAD_PARAMETER_VALUE, true, \
+                           PS_ERRORTEXT_psImage_PARAMETER_OUTOF_TYPERANGE, \
+                           "vmin",vmin, PS_TYPE_##type##_NAME, \
+                           (psF64)PS_MIN_##type,(psF64)PS_MAX_##type); \
+            } \
+            if (vmax > PS_MAX_##type || vmax < PS_MIN_##type) { \
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageClip", \
+                           PS_ERR_BAD_PARAMETER_VALUE, true, \
+                           PS_ERRORTEXT_psImage_PARAMETER_OUTOF_TYPERANGE, \
+                           "vmax",vmax, PS_TYPE_##type##_NAME, \
+                           (psF64)PS_MIN_##type,(psF64)PS_MAX_##type); \
+            } \
+            for (unsigned int row = 0;row<numRows;row++) { \
+                ps##type* inputRow = input->data.type[row]; \
+                for (unsigned int col = 0; col < numCols; col++) { \
+                    if ((psF64)inputRow[col] < min) { \
+                        inputRow[col] = (ps##type)vmin; \
+                        numClipped++; \
+                    } else if ((psF64)inputRow[col] > max) { \
+                        inputRow[col] = (ps##type)vmax; \
+                        numClipped++; \
+                    } \
+                } \
+            } \
+        } \
+        break;
+
+        #define psImageClipCaseComplex(type,absfcn)\
+    case PS_TYPE_##type: { \
+            if (vmin < PS_MIN_##type || vmin > PS_MAX_##type) { \
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageClip", \
+                           PS_ERR_BAD_PARAMETER_VALUE, true, \
+                           PS_ERRORTEXT_psImage_PARAMETER_OUTOF_TYPERANGE, \
+                           "vmin",vmin, PS_TYPE_##type##_NAME, \
+                           (psF64)PS_MIN_##type,(psF64)PS_MAX_##type); \
+            } \
+            if (vmax > PS_MAX_##type || vmax < PS_MIN_##type) { \
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageClip", \
+                           PS_ERR_BAD_PARAMETER_VALUE, true, \
+                           PS_ERRORTEXT_psImage_PARAMETER_OUTOF_TYPERANGE, \
+                           "vmax",vmax, PS_TYPE_##type##_NAME, \
+                           (psF64)PS_MIN_##type,(psF64)PS_MAX_##type); \
+            } \
+            for (unsigned int row = 0;row<numRows;row++) { \
+                ps##type* inputRow = input->data.type[row]; \
+                for (unsigned int col = 0; col < numCols; col++) { \
+                    if (absfcn(inputRow[col]) < min) { \
+                        inputRow[col] = (ps##type)vmin; \
+                        numClipped++; \
+                    } else if (absfcn(inputRow[col]) > max) { \
+                        inputRow[col] = (ps##type)vmax; \
+                        numClipped++; \
+                    } \
+                } \
+            } \
+        } \
+        break;
+
+        psImageClipCase(S8)
+        psImageClipCase(S16)
+        psImageClipCase(S32)                   // Not a requirement
+        //        psImageClipCase(S64)            Not a requirement
+        psImageClipCase(U8)
+        psImageClipCase(U16)
+        //        psImageClipCase(U32)            Not a requirement
+        //        psImageClipCase(U64)            Not a requirement
+        psImageClipCase(F32)
+        psImageClipCase(F64)
+        psImageClipCaseComplex(C32, cabsf)
+        psImageClipCaseComplex(C64, cabs)
+
+    default: {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,input->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageClip",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                       typeStr);
+        }
+    }
+
+    return numClipped;
+}
+
+int psImageClipNaN(psImage* input,
+                   psF64 value)
+{
+    int numClipped = 0;
+    unsigned int numRows;
+    unsigned int numCols;
+
+    if (input == NULL) {
+        return 0;
+    }
+    numRows = input->numRows;
+    numCols = input->numCols;
+
+    switch (input->type.type) {
+
+        #define psImageClipNaNCase(type) \
+    case PS_TYPE_##type: \
+        for (unsigned int row = 0;row<numRows;row++) { \
+            ps##type* inputRow = input->data.type[row]; \
+            for (unsigned int col = 0; col < numCols; col++) { \
+                if (! isfinite(inputRow[col])) { \
+                    inputRow[col] = (ps##type)value; \
+                    numClipped++; \
+                } \
+            } \
+        } \
+        break;
+
+        psImageClipNaNCase(F32)
+        psImageClipNaNCase(F64)
+        psImageClipNaNCase(C32)
+        psImageClipNaNCase(C64)
+
+    default: {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,input->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageClipNaN",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                       typeStr);
+        }
+    }
+
+    return numClipped;
+}
+
+int psImageOverlaySection(psImage* image,
+                          const psImage* overlay,
+                          int col0,
+                          int row0,
+                          const char *op)
+{
+    unsigned int imageNumRows;
+    unsigned int imageNumCols;
+    unsigned int overlayNumRows;
+    unsigned int overlayNumCols;
+    unsigned int imageRowLimit;
+    unsigned int imageColLimit;
+    psElemType type;
+
+    if (image == NULL || overlay == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageOverlaySection",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        return 1;
+    }
+
+    if (op == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageOverlaySection",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImageManip_OPERATION_NULL);
+        return 1;
+    }
+
+    type = image->type.type;
+
+    if (type != overlay->type.type) {
+        char* typeStr;
+        char* typeStrOverlay;
+        PS_TYPE_NAME(typeStr,type);
+        PS_TYPE_NAME(typeStrOverlay,overlay->type.type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageOverlaySection",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImageManip_OVERLAY_TYPE_MISMATCH,
+                   typeStrOverlay, typeStr);
+        return 2;
+    }
+
+    imageNumRows = image->numRows;
+    imageNumCols = image->numCols;
+    overlayNumRows = overlay->numRows;
+    overlayNumCols = overlay->numCols;
+    imageRowLimit = row0 + overlayNumRows;
+    imageColLimit = col0 + overlayNumCols;
+
+    /* check to see if overlay is within the input image */
+    if ( row0 < 0 ||
+            col0 < 0 ||
+            imageRowLimit > imageNumRows ||
+            imageColLimit > imageNumCols) {
+
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageOverlaySection",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImage_SUBSET_RANGE_INVALID,
+                   col0, imageColLimit, row0, imageRowLimit,
+                   imageNumCols, imageNumRows);
+        return 3;
+    }
+
+    switch (type) {
+
+        #define psImageOverlayCase(DATATYPE) \
+    case PS_TYPE_##DATATYPE: \
+        for (unsigned int row=row0;row<imageRowLimit;row++) { \
+            ps##DATATYPE* imageRow = image->data.DATATYPE[row]; \
+            ps##DATATYPE* overlayRow = overlay->data.DATATYPE[row-row0]; \
+            for (unsigned int col=col0;col<imageColLimit;col++) { \
+                switch (*op) { \
+                case '+': \
+                    imageRow[col] += overlayRow[col-col0]; \
+                    break; \
+                case '-': \
+                    imageRow[col] -= overlayRow[col-col0]; \
+                    break; \
+                case '*': \
+                    imageRow[col] *= overlayRow[col-col0]; \
+                    break; \
+                case '/': \
+                    imageRow[col] /= overlayRow[col-col0]; \
+                    break; \
+                case '=': \
+                    imageRow[col] = overlayRow[col-col0]; \
+                    break; \
+                default: \
+                    psErrorMsg(PS_ERRORNAME_DOMAIN "psImageOverlaySection", \
+                               PS_ERR_BAD_PARAMETER_VALUE, true, \
+                               PS_ERRORTEXT_psImageManip_OVERLAY_OPERATOR_INVALID, \
+                               op); \
+                    return 5; \
+                } \
+            } \
+        } \
+        break;
+
+        psImageOverlayCase(U8);
+        psImageOverlayCase(U16);
+        //        psImageOverlayCase(U32);       Not a requirement
+        //        psImageOverlayCase(U64);       Not a requirement
+        psImageOverlayCase(S8);
+        psImageOverlayCase(S16);
+        //        psImageOverlayCase(S32);       Not a requirement
+        //        psImageOverlayCase(S64);       Not a requirement
+        psImageOverlayCase(F32);
+        psImageOverlayCase(F64);
+        psImageOverlayCase(C32);
+        psImageOverlayCase(C64);
+
+    default: {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageOverlaySection",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                       typeStr);
+            return 6;
+        }
+    }
+
+    return 0;
+}
+
+int psImageClipComplexRegion(psImage* input,
+                             psC64 min,
+                             psC64 vmin,
+                             psC64 max,
+                             psC64 vmax)
+{
+    int numClipped = 0;
+    unsigned int numRows;
+    unsigned int numCols;
+    psF64 realMin = creal(min);
+    psF64 imagMin = cimag(min);
+    psF64 realMax = creal(max);
+    psF64 imagMax = cimag(max);
+
+    if (input == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageClipComplexRegion",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        return 0;
+    }
+
+    if (realMax < realMin) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageClipComplexRegion",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImageManip_MAXMIN_REAL,
+                   (double)realMin, (double)realMax);
+        return 0;
+    }
+    if (imagMax < imagMin) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageClipComplexRegion",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImageManip_MAXMIN_IMAG,
+                   (double)imagMin, (double)imagMax);
+        return 0;
+    }
+
+    numRows = input->numRows;
+    numCols = input->numCols;
+
+    #define psImageClipComplexRegionCase(type,realfcn,imagfcn) \
+case PS_TYPE_##type: { \
+        if (realfcn(vmin) < PS_MIN_##type || imagfcn(vmin) < PS_MIN_##type || \
+                realfcn(vmin) > PS_MAX_##type || imagfcn(vmin) > PS_MAX_##type ) { \
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageClipComplexRegion", \
+                       PS_ERR_BAD_PARAMETER_VALUE, true, \
+                       PS_ERRORTEXT_psImageManip_CLIP_VALUE_INVALID, \
+                       "vmin", creal(vmin), cimag(vmin), \
+                       PS_TYPE_##type##_NAME, PS_MIN_##type, PS_MAX_##type); \
+            break; \
+        } \
+        if (realfcn(vmax) > PS_MAX_##type || imagfcn(vmax) > PS_MAX_##type || \
+                realfcn(vmax) < PS_MIN_##type || imagfcn(vmax) < PS_MIN_##type ) { \
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageClipComplexRegion", \
+                       PS_ERR_BAD_PARAMETER_VALUE, true, \
+                       PS_ERRORTEXT_psImageManip_CLIP_VALUE_INVALID, \
+                       "vmax", creal(vmax), cimag(vmax), \
+                       PS_TYPE_##type##_NAME, PS_MIN_##type, PS_MAX_##type); \
+            break; \
+        } \
+        for (unsigned int row = 0;row<numRows;row++) { \
+            ps##type* inputRow = input->data.type[row]; \
+            for (unsigned int col = 0; col < numCols; col++) { \
+                if ( (realfcn(inputRow[col]) > realMax) || (imagfcn(inputRow[col]) > imagMax) ) { \
+                    inputRow[col] = (ps##type)vmax; \
+                    numClipped++; \
+                } else if ( (realfcn(inputRow[col]) < realMin) || (imagfcn(inputRow[col]) < imagMin) ){ \
+                    inputRow[col] = (ps##type)vmin; \
+                    numClipped++; \
+                } \
+            } \
+        } \
+    } \
+    break;
+
+    switch (input->type.type) {
+
+        psImageClipComplexRegionCase(C32, crealf, cimagf)
+        psImageClipComplexRegionCase(C64, creal, cimag)
+
+    default: {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,input->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageClipComplexRegion",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                       typeStr);
+        }
+    }
+
+    return numClipped;
+}
+
+psImage* psImageRebin(psImage* out,
+                      const psImage* in,
+                      const psImage* restrict mask,
+                      psMaskType maskVal,
+                      unsigned int scale,
+                      const psStats* stats)
+{
+    int inRows;
+    int inCols;
+    int outRows;
+    int outCols;
+    psVector* vec;                     // vector to hold the values of a single bin.
+    psVector* maskVec = NULL;          // vector to hold the mask of a single bin.
+    psMaskType* maskData = NULL;
+    psStats* myStats;
+    double statVal;
+
+    if (in == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRebin",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    if (scale < 1) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRebin",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImageManip_SCALE_NOT_POSITIVE,
+                   scale);
+        psFree(out);
+        return NULL;
+    }
+
+    if (stats == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRebin",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_STAT_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    if (p_psGetStatValue(stats, &statVal) == false) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRebin",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImage_BAD_STAT,
+                   stats->options);
+        psFree(out);
+        return NULL;
+    }
+
+    vec = psVectorAlloc(scale * scale, in->type.type);
+
+    if (mask != NULL) {
+        if (mask->type.type != PS_TYPE_MASK) {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,mask->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRebin",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE,
+                       typeStr, PS_TYPE_MASK_NAME);
+            psFree(out);
+            psFree(vec);
+            return NULL;
+        }
+        maskVec = psVectorAlloc(scale * scale, PS_TYPE_MASK);
+        maskData = maskVec->data.PS_TYPE_MASK_DATA;
+    }
+
+    myStats = psAlloc(sizeof(psStats));
+    *myStats = *stats;
+
+    // create output image.
+    inRows = in->numRows;
+    inCols = in->numCols;
+    outRows = (inRows + scale - 1) / scale;     // round-up for remainders
+    outCols = (inCols + scale - 1) / scale;     // round-up for remainders
+    out = psImageRecycle(out, outCols, outRows, in->type.type);
+
+    #define PS_IMAGE_REBIN_CASE(type) \
+case PS_TYPE_##type: { \
+        ps##type* outRowData; \
+        ps##type* vecData = vec->data.type; \
+        psMaskType* inRowMask = NULL; \
+        for (int row = 0; row < outRows; row++) { \
+            outRowData = out->data.type[row]; \
+            int inCurrentRow = row*scale; \
+            int inNextRow = (row+1)*scale; \
+            for (int col = 0; col < outCols; col++) { \
+                int inCurrentCol = col*scale; \
+                int inNextCol = (col+1)*scale; \
+                int n = 0; \
+                for (int inRow = inCurrentRow; inRow < inNextRow && inRow < inRows; inRow++) { \
+                    ps##type* inRowData = in->data.type[inRow]; \
+                    if (mask != NULL) { \
+                        inRowMask = mask->data.PS_TYPE_MASK_DATA[inRow]; \
+                    } \
+                    for (int inCol = inCurrentCol; inCol < inNextCol && inCol < inCols; inCol++) { \
+                        if (maskData != NULL) { \
+                            maskData[n] = inRowMask[inCol]; \
+                        } \
+                        vecData[n++] = inRowData[inCol]; \
+                    } \
+                } \
+                vec->n = n; \
+                myStats = psVectorStats(myStats,vec,maskVec,maskVal); \
+                p_psGetStatValue(myStats,&statVal); \
+                outRowData[col] = (ps##type)statVal; \
+            } \
+        } \
+    } \
+    break;
+
+    switch (in->type.type) {
+        //        PS_IMAGE_REBIN_CASE(U8);       Not valid since psVectorStats doesn't allow
+        PS_IMAGE_REBIN_CASE(U16);
+        //        PS_IMAGE_REBIN_CASE(U32);      Not a requirement
+        //        PS_IMAGE_REBIN_CASE(U64);      Not a requirement
+        PS_IMAGE_REBIN_CASE(S8);
+        //        PS_IMAGE_REBIN_CASE(S16);      Not valid since psVectorStats doesn't allow
+        //        PS_IMAGE_REBIN_CASE(S32);      Not a requirement
+        //        PS_IMAGE_REBIN_CASE(S64);      Not a requirement
+        PS_IMAGE_REBIN_CASE(F32);
+        PS_IMAGE_REBIN_CASE(F64);
+        //        PS_IMAGE_REBIN_CASE(C32);      Not valid since psVectorStats doesn't allow
+        //        PS_IMAGE_REBIN_CASE(C64);      Not valid since psVectorStats doesn't allow
+
+    default: {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,in->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRebin",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                       typeStr);
+            psFree(out);
+            out = NULL;
+        }
+    }
+
+    psFree(vec);
+    psFree(maskVec);
+    psFree(myStats);
+
+    return out;
+}
+
+psImage* psImageResample(psImage* out,
+                         const psImage* in,
+                         int scale,
+                         psImageInterpolateMode mode)
+{
+    int outRows;
+    int outCols;
+    float invScale;
+
+    if (in == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageResample",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    if (scale < 1) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageResample",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImageManip_SCALE_NOT_POSITIVE,
+                   scale);
+        psFree(out);
+        return NULL;
+    }
+
+    if (mode < PS_INTERPOLATE_FLAT || mode >= PS_INTERPOLATE_NUM_MODES) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageResample",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImageManip_INTERPOLATION_MODE_UNSUPPORTED,
+                   mode);
+        psFree(out);
+        return NULL;
+    }
+
+    // create an output image of the same size
+    // and type
+    outRows = in->numRows * scale;
+    outCols = in->numCols * scale;
+    invScale = 1.0f / (float)scale;
+
+    #define PSIMAGE_RESAMPLE_CASE(TYPE) \
+case PS_TYPE_##TYPE: { \
+        out = psImageRecycle(out,outCols, outRows, PS_TYPE_##TYPE); \
+        for (int row=0;row<outRows;row++) { \
+            ps##TYPE* rowData = out->data.TYPE[row]; \
+            float inRow = (float)row * invScale; \
+            for (int col=0;col<outCols;col++) { \
+                rowData[col] = psImagePixelInterpolate(in,(float)col*invScale,inRow,NULL,0,0,mode); \
+            } \
+        }  \
+        break; \
+    }
+
+    switch (in->type.type) {
+        PSIMAGE_RESAMPLE_CASE(U8)
+        PSIMAGE_RESAMPLE_CASE(U16)
+        PSIMAGE_RESAMPLE_CASE(U32)
+        PSIMAGE_RESAMPLE_CASE(U64)
+        PSIMAGE_RESAMPLE_CASE(S8)
+        PSIMAGE_RESAMPLE_CASE(S16)
+        PSIMAGE_RESAMPLE_CASE(S32)
+        PSIMAGE_RESAMPLE_CASE(S64)
+        PSIMAGE_RESAMPLE_CASE(F32)
+        PSIMAGE_RESAMPLE_CASE(F64)
+        PSIMAGE_RESAMPLE_CASE(C32)
+        PSIMAGE_RESAMPLE_CASE(C64)
+    default: {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,in->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageResample",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                       typeStr);
+            psFree(out);
+            out = NULL;
+        }
+    }
+
+    return out;
+}
+
+psImage* psImageRoll(psImage* out,
+                     const psImage* in,
+                     int dx,
+                     int dy)
+{
+    int outRows;
+    int outCols;
+    int elementSize;
+
+    if (in == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRoll",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(out);
+        return NULL;
+    }
+    // create an output image of the same size
+    // and type
+    outRows = in->numRows;
+    outCols = in->numCols;
+    elementSize = PSELEMTYPE_SIZEOF(in->type.type);
+    out = psImageRecycle(out, outCols, outRows, in->type.type);
+
+    // make dx and dy between 0 and outCols or
+    // outRows, respectively
+    dx = dx % outCols;
+    dy = dy % outRows;
+    if (dx < 0) {
+        dx += outCols;
+    }
+    if (dy < 0) {
+        dy += outRows;
+    }
+
+    int segment1Size = elementSize * (outCols - dx);
+    int segment2Size = elementSize * dx;
+
+    for (int row = 0; row < outRows; row++) {
+        int inRowNumber = row + dy;
+
+        if (inRowNumber >= outRows) {
+            inRowNumber -= outRows;
+        }
+        psU8* inRow = in->data.U8[inRowNumber]; // use byte arithmetic for all types
+        psU8* outRow = out->data.U8[row];
+
+        memcpy(outRow, inRow + segment2Size, segment1Size);
+        memcpy(outRow + segment1Size, inRow, segment2Size);
+    }
+
+    return out;
+}
+
+psImage* psImageRotate(psImage* out,
+                       const psImage* in,
+                       float angle,
+                       psC64 unexposedValue,
+                       psImageInterpolateMode mode)
+{
+    if (in == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRotate",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(out);
+        return NULL;
+    }
+    // put the angle in the range of 0...360.
+    angle = angle - 360.0f * floor(angle / 360.0f);
+
+    if (fabsf(angle - 90.0f) < FLT_EPSILON) {
+        // perform 1/4 rotate counter-clockwise
+        int numRows = in->numCols;
+        int numCols = in->numRows;
+        int lastCol = numCols - 1;
+        psElemType type = in->type.type;
+
+        out = psImageRecycle(out, numCols, numRows, type);
+
+        #define PSIMAGE_ROTATE_LEFT_90(TYPE) \
+    case PS_TYPE_##TYPE: { \
+            ps##TYPE** inData = in->data.TYPE; \
+            for (int row=0;row<numRows;row++) { \
+                ps##TYPE* outRow = out->data.TYPE[row]; \
+                for (int col=0;col<numCols;col++) { \
+                    outRow[col] = inData[lastCol-col][row]; \
+                } \
+            } \
+        } \
+        break;
+
+        switch (type) {
+            PSIMAGE_ROTATE_LEFT_90(U8);
+            PSIMAGE_ROTATE_LEFT_90(U16);
+            //            PSIMAGE_ROTATE_LEFT_90(U32);      Not a requirement
+            //            PSIMAGE_ROTATE_LEFT_90(U64);      Not a requirement
+            PSIMAGE_ROTATE_LEFT_90(S8);
+            PSIMAGE_ROTATE_LEFT_90(S16);
+            //            PSIMAGE_ROTATE_LEFT_90(S32);      Not a requirement
+            //            PSIMAGE_ROTATE_LEFT_90(S64);      Not a requirement
+            PSIMAGE_ROTATE_LEFT_90(F32);
+            PSIMAGE_ROTATE_LEFT_90(F64);
+            PSIMAGE_ROTATE_LEFT_90(C32);
+            PSIMAGE_ROTATE_LEFT_90(C64);
+
+        default: {
+                char* typeStr;
+                PS_TYPE_NAME(typeStr,type);
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRotate",
+                           PS_ERR_BAD_PARAMETER_TYPE, true,
+                           PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                           typeStr);
+                psFree(out);
+                return NULL;
+            }
+        }
+    } else if (fabsf(angle - 180.0f) < FLT_EPSILON) {
+        // perform 1/2 rotate
+        int numRows = in->numRows;
+        int lastRow = numRows - 1;
+        int numCols = in->numCols;
+        int lastCol = numCols - 1;
+        psElemType type = in->type.type;
+
+        out = psImageRecycle(out, numCols, numRows, type);
+
+        #define PSIMAGE_ROTATE_180_CASE(TYPE) \
+    case PS_TYPE_##TYPE: { \
+            for (int row=0;row<numRows;row++) { \
+                ps##TYPE* outRow = out->data.TYPE[row]; \
+                ps##TYPE* inRow = in->data.TYPE[lastRow-row]; \
+                for (int col=0;col<numCols;col++) { \
+                    outRow[col] = inRow[lastCol - col]; \
+                } \
+            } \
+        } \
+        break;
+
+        switch (type) {
+            PSIMAGE_ROTATE_180_CASE(U8);
+            PSIMAGE_ROTATE_180_CASE(U16);
+            //            PSIMAGE_ROTATE_180_CASE(U32);    Not a requirement
+            //            PSIMAGE_ROTATE_180_CASE(U64);    Not a requirement
+            PSIMAGE_ROTATE_180_CASE(S8);
+            PSIMAGE_ROTATE_180_CASE(S16);
+            //            PSIMAGE_ROTATE_180_CASE(S32);    Not a requirement
+            //            PSIMAGE_ROTATE_180_CASE(S64);    Not a requirement
+            PSIMAGE_ROTATE_180_CASE(F32);
+            PSIMAGE_ROTATE_180_CASE(F64);
+            PSIMAGE_ROTATE_180_CASE(C32);
+            PSIMAGE_ROTATE_180_CASE(C64);
+
+        default: {
+                char* typeStr;
+                PS_TYPE_NAME(typeStr,type);
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRotate",
+                           PS_ERR_BAD_PARAMETER_TYPE, true,
+                           PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                           typeStr);
+                psFree(out);
+                return NULL;
+            }
+        }
+    } else if (fabsf(angle - 270.0f) < FLT_EPSILON) {
+        // perform 1/4 rotate clockwise
+        int numRows = in->numCols;
+        int lastRow = numRows - 1;
+        int numCols = in->numRows;
+        psElemType type = in->type.type;
+
+        out = psImageRecycle(out, numCols, numRows, type);
+
+        #define PSIMAGE_ROTATE_RIGHT_90(TYPE) \
+    case PS_TYPE_##TYPE: { \
+            ps##TYPE** inData = in->data.TYPE; \
+            for (int row=0;row<numRows;row++) { \
+                ps##TYPE* outRow = out->data.TYPE[row]; \
+                for (int col=0;col<numCols;col++) { \
+                    outRow[col] = inData[col][lastRow-row]; \
+                } \
+            } \
+        } \
+        break;
+
+        switch (type) {
+            PSIMAGE_ROTATE_RIGHT_90(U8);
+            PSIMAGE_ROTATE_RIGHT_90(U16);
+            //            PSIMAGE_ROTATE_RIGHT_90(U32);     Not a requirement
+            //            PSIMAGE_ROTATE_RIGHT_90(U64);     Not a requirement
+            PSIMAGE_ROTATE_RIGHT_90(S8);
+            PSIMAGE_ROTATE_RIGHT_90(S16);
+            //            PSIMAGE_ROTATE_RIGHT_90(S32);     Not a requirement
+            //            PSIMAGE_ROTATE_RIGHT_90(S64);     Not a requirement
+            PSIMAGE_ROTATE_RIGHT_90(F32);
+            PSIMAGE_ROTATE_RIGHT_90(F64);
+            PSIMAGE_ROTATE_RIGHT_90(C32);
+            PSIMAGE_ROTATE_RIGHT_90(C64);
+
+        default: {
+                char* typeStr;
+                PS_TYPE_NAME(typeStr,type);
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRotate",
+                           PS_ERR_BAD_PARAMETER_TYPE, true,
+                           PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                           typeStr);
+                psFree(out);
+                return NULL;
+            }
+        }
+    } else if (fabsf(angle) < FLT_EPSILON) {
+        out = psImageCopy(out, in, in->type.type);
+    } else {
+        psElemType type = in->type.type;
+        int numRows = in->numRows;
+        int numCols = in->numCols;
+        float centerX = (float)(numCols) / 2.0f;
+        float centerY = (float)(numRows) / 2.0f;
+        float t = angle * (3.14159265358f / 180.0f);
+        double cosT = cosf(t);
+        double sinT = sinf(t);
+
+        // calculate the corners of the rotated image so we know the proper output image size.
+        // x' = x cos(t) + y sin(t); i.e, x' = (x-centerX)*cosT + (y-centerY)*sinT;
+        // y' = y cos(t) - x sin(t); i.e. y' = (y-centerY)*cosT - (x-centerX)*sinT;
+
+        int outCols = ceil(abs(numCols * cosT) + abs(numRows * sinT)) + 1;
+        int outRows = ceil(abs(numCols * sinT) + abs(numRows * cosT)) + 1;
+        float minX = (float)outCols / -2.0f;
+        int intMinY = outRows / -2;
+
+        out = psImageRecycle(out, outCols, outRows, type);
+
+        /* optimized public domain rotation routine by Karl Lager
+         * 
+         * float cosT,sinT; 
+         * cosT = cos(t); 
+         * sinT = sin(t); 
+         * for (y = min_y; y <= max_y; y++) { 
+         *     x' = min_x * cosT + y * sinT + x1'; 
+         *     y' = y * cosT - min_x * sinT + y1'; 
+         *     for (x = min_x; x <= max_x; x++) { 
+         *         if (x', y') is in the bounds of the bitmap, get pixel
+         *            (x', y') and plot the pixel to (x, y) on screen. 
+         *         x' += cosT; 
+         *         y' -= sinT; 
+         *     }
+         * } 
+         */
+
+        // precalculate some figures that are used within loop
+        float minXTimesCosTPlusCenterX = minX * cosT + centerX;
+        float CenterYMinusminXTimesSinT = centerY - minX * sinT;
+
+        #define PSIMAGE_ROTATE_ARBITRARY_LOOP(TYPE,MODE) { \
+            if (creal(unexposedValue) < PS_MIN_##TYPE || \
+                    creal(unexposedValue) > PS_MAX_##TYPE || \
+                    cimag(unexposedValue) < PS_MIN_##TYPE || \
+                    cimag(unexposedValue) > PS_MAX_##TYPE) { \
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRotate", \
+                           PS_ERR_BAD_PARAMETER_VALUE, true, \
+                           PS_ERRORTEXT_psImageManip_CLIP_VALUE_INVALID, \
+                           "unexposedValue", \
+                           creal(unexposedValue),cimag(unexposedValue), \
+                           PS_TYPE_##TYPE##_NAME,  \
+                           (double)PS_MIN_##TYPE,(double)PS_MAX_##TYPE); \
+                psFree(out); \
+                out = NULL; \
+                break; \
+            } \
+            float inX; \
+            float inY; \
+            ps##TYPE* outRow; \
+            for (int y = 0; y < outRows; y++) { \
+                inX = minXTimesCosTPlusCenterX + (y+intMinY) * sinT; \
+                inY = CenterYMinusminXTimesSinT + (y+intMinY) * cosT; \
+                outRow = out->data.TYPE[y]; \
+                for (int x = 0; x < outCols; x++) { \
+                    outRow[x] = p_psImagePixelInterpolate##MODE##_##TYPE(in,inX,inY,NULL,0,unexposedValue); \
+                    inX += cosT; \
+                    inY -= sinT; \
+                } \
+            } \
+        }
+
+        #define PSIMAGE_ROTATE_ARBITRARY_CASE(MODE) \
+    case PS_INTERPOLATE_##MODE: \
+        switch (type) { \
+        case PS_TYPE_U8: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(U8,MODE); \
+            break; \
+        case PS_TYPE_U16: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(U16,MODE); \
+            break; \
+            /*        case PS_TYPE_U32:    Not a requirement */ \
+            /*            PSIMAGE_ROTATE_ARBITRARY_LOOP(U32,MODE); */ \
+            /*            break; */ \
+            /*        case PS_TYPE_U64:    Not a requirement */ \
+            /*            PSIMAGE_ROTATE_ARBITRARY_LOOP(U64,MODE); */ \
+            /*            break; */ \
+        case PS_TYPE_S8: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(S8,MODE); \
+            break; \
+        case PS_TYPE_S16: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(S16,MODE); \
+            break; \
+            /*        case PS_TYPE_S32:    Not a requirement */ \
+            /*            PSIMAGE_ROTATE_ARBITRARY_LOOP(S32,MODE); */ \
+            /*            break; */ \
+            /*        case PS_TYPE_S64:    Not a requirement */ \
+            /*            PSIMAGE_ROTATE_ARBITRARY_LOOP(S64,MODE); */ \
+            /*            break; */ \
+        case PS_TYPE_F32: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(F32,MODE); \
+            break; \
+        case PS_TYPE_F64: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(F64,MODE); \
+            break; \
+        case PS_TYPE_C32: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(C32,MODE); \
+            break; \
+        case PS_TYPE_C64: \
+            PSIMAGE_ROTATE_ARBITRARY_LOOP(C64,MODE); \
+            break; \
+        default: { \
+                char* typeStr; \
+                PS_TYPE_NAME(typeStr,type); \
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRotate", \
+                           PS_ERR_BAD_PARAMETER_TYPE, true, \
+                           PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED, \
+                           typeStr); \
+                psFree(out); \
+                out = NULL; \
+            } \
+        } \
+        break;
+
+        switch (mode) {
+            PSIMAGE_ROTATE_ARBITRARY_CASE(FLAT);
+            PSIMAGE_ROTATE_ARBITRARY_CASE(BILINEAR);
+        default:
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRotate",
+                       PS_ERR_BAD_PARAMETER_VALUE, true,
+                       PS_ERRORTEXT_psImageManip_INTERPOLATION_MODE_UNSUPPORTED,
+                       mode);
+            psFree(out);
+            out = NULL;
+        }
+    }
+
+    return out;
+}
+
+psImage* psImageShift(psImage* out,
+                      const psImage* in,
+                      float dx,
+                      float dy,
+                      psC64 unexposedValue,
+                      psImageInterpolateMode mode)
+{
+    int outRows;
+    int outCols;
+    int elementSize;
+    psElemType type;
+
+    if (in == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageShift",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(out);
+        return NULL;
+    }
+    // create an output image of the same size
+    // and type
+    outRows = in->numRows;
+    outCols = in->numCols;
+    type = in->type.type;
+    elementSize = PSELEMTYPE_SIZEOF(type);
+    out = psImageRecycle(out, outCols, outRows, type);
+
+    #define PSIMAGE_SHIFT_CASE(MODE,TYPE) \
+case PS_TYPE_##TYPE: \
+    if (creal(unexposedValue) < PS_MIN_##TYPE || \
+            creal(unexposedValue) > PS_MAX_##TYPE || \
+            cimag(unexposedValue) < PS_MIN_##TYPE || \
+            cimag(unexposedValue) > PS_MAX_##TYPE) { \
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageShift", \
+                   PS_ERR_BAD_PARAMETER_VALUE, true, \
+                   PS_ERRORTEXT_psImageManip_CLIP_VALUE_INVALID, \
+                   "unexposedValue", \
+                   creal(unexposedValue),cimag(unexposedValue), \
+                   PS_TYPE_##TYPE##_NAME,  \
+                   (double)PS_MIN_##TYPE,(double)PS_MAX_##TYPE); \
+        psFree(out); \
+        out = NULL; \
+        break; \
+    } \
+    for (int row=0;row<outRows;row++) { \
+        ps##TYPE* outRow = out->data.TYPE[row]; \
+        float y = dy+(float)row; \
+        for (int col=0;col<outCols;col++) { \
+            outRow[col] = p_psImagePixelInterpolate##MODE##_##TYPE( \
+                          in,dx+(float)col,y,NULL,0,unexposedValue); \
+        } \
+    } \
+    break;
+
+    #define PSIMAGE_SHIFT_ARBITRARY_CASE(MODE) \
+case PS_INTERPOLATE_##MODE: \
+    switch (in->type.type) { \
+        PSIMAGE_SHIFT_CASE(MODE,U8);  \
+        PSIMAGE_SHIFT_CASE(MODE,U16); \
+        /*        PSIMAGE_SHIFT_CASE(MODE,U32);     Not a requirement */ \
+        /*        PSIMAGE_SHIFT_CASE(MODE,U64);     Not a requirement */ \
+        PSIMAGE_SHIFT_CASE(MODE,S8);  \
+        PSIMAGE_SHIFT_CASE(MODE,S16); \
+        /*        PSIMAGE_SHIFT_CASE(MODE,S32);     Not a requirement */ \
+        /*        PSIMAGE_SHIFT_CASE(MODE,S64);     Not a requirement */ \
+        PSIMAGE_SHIFT_CASE(MODE,F32); \
+        PSIMAGE_SHIFT_CASE(MODE,F64); \
+        PSIMAGE_SHIFT_CASE(MODE,C32); \
+        PSIMAGE_SHIFT_CASE(MODE,C64); \
+        \
+    default: { \
+            char* typeStr; \
+            PS_TYPE_NAME(typeStr,type); \
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRotate", \
+                       PS_ERR_BAD_PARAMETER_TYPE, true, \
+                       PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED, \
+                       typeStr); \
+            psFree(out); \
+            out = NULL; \
+        } \
+    } \
+    break;
+
+
+    switch (mode) {
+        PSIMAGE_SHIFT_ARBITRARY_CASE(FLAT);
+        PSIMAGE_SHIFT_ARBITRARY_CASE(BILINEAR);
+    default:
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageShift",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImageManip_INTERPOLATION_MODE_UNSUPPORTED,
+                   mode);
+        psFree(out);
+        out = NULL;
+    }
+
+    return out;
+}
Index: /branches/rel3/psLib/src/image/psImageManip.h
===================================================================
--- /branches/rel3/psLib/src/image/psImageManip.h	(revision 2163)
+++ /branches/rel3/psLib/src/image/psImageManip.h	(revision 2163)
@@ -0,0 +1,182 @@
+
+/** @file  psImageManip.h
+ *
+ *  @brief Contains basic image pixel and geometry manipulation operations, as
+ *         specified in the PSLIB SDRS sections "Image Pixel Manipulations" and
+ *         "Image Geometry Manipulations".
+ *
+ *  @ingroup Image
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-27 19:49:54 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#ifndef PS_IMAGE_MANIP_H
+#define PS_IMAGE_MANIP_H
+
+#include "psImage.h"
+
+/// @addtogroup Image
+/// @{
+
+/** Clip image values outside of range to given values
+ *
+ *  All pixels with values less than min are set to the value vmin.  all pixels
+ *  with values greater than max are set to the value vmax. This function is
+ *  defined for psU8, psU16, psS8, psS16, psF32, psF64, psC32, and psC64.
+ *
+ *  @return int     The number of clipped pixels
+ */
+int psImageClip(
+    psImage* input,                    ///< the image to clip
+    psF64 min,                         ///< the minimum image value allowed
+    psF64 vmin,                        ///< the value pixels < min are set to
+    psF64 max,                         ///< the maximum image value allowed
+    psF64 vmax                         ///< the value pixels > max are set to
+);
+
+/** Clip image values outside of a specified complex region
+ *
+ *  All pixels outside of the rectangular region in complex space formed by
+ *  the min and max input parameters are set to the value vmax (if either
+ *  the real or imaginary portion exceeds the respective max values), or vmin. 
+ *  This function is defined for psC32, and psC64 imagery only.
+ *
+ *  @return int     The number of clipped pixels
+ */
+int psImageClipComplexRegion(
+    psImage* input,                    ///< the image to clip
+    psC64 min,                         ///< the minimum image value allowed
+    psC64 vmin,                        ///< the value pixels < min are set to
+    psC64 max,                         ///< the maximum image value allowed
+    psC64 vmax                         ///< the value pixels > max are set to
+);
+
+/** Clip NaN image pixels to given value.
+ *
+ *  Pixels with NaN, +Inf, or -Inf values are set to the specified value. This
+ *  function is defined for psF32, psF64, psC32, and psC64.
+ *
+ *  @return int     The number of clipped pixels
+ */
+int psImageClipNaN(
+    psImage* input,                    ///< the image to clip
+    psF64 value                        ///< the value to set all NaN/Inf values to
+);
+
+/** Overlay subregion of image with another image
+ *
+ *  Replace the pixels in the image which correspond to the pixels in OVERLAY
+ *  with values derived from the IMAGE and OVERLAY based on the given operator
+ *  OP.  Valid operators are "=" (set image value to OVERLAY value), "+" (add
+ *  OVERLAY value to image value), "-" (subtract OVERLAY from image), "*"
+ *  (multiply OVERLAY times image), "/" (divide image by OVERLAY).  This
+ *  function is defined for psU8, psS8, psS16, psF32, psF64, psC32, and psC64.
+ *
+ *  @return int         0 if success, non-zero if failed.
+ */
+int psImageOverlaySection(
+    psImage* image,                    ///< target image
+    const psImage* overlay,            ///< the overlay image
+    int col0,                          ///< the column to start overlay
+    int row0,                          ///< the row to start overlay
+    const char *op                     ///< the operation to perform for overlay
+);
+
+/** Rebin image to new scale.
+ *
+ *  A new image is constructed in which the dimensions are reduced by a factor of
+ *  1/scale.  The scale, always a positive number, is equal in each dimension and
+ *  specified the number of pixels used to define a new pixel in the output image.
+ *  The output image is generated from all input image pixels. This function is 
+ *  defined for psU8, psS8, psS16, psF32, psF64, psC32, and psC64.
+ *
+ *  @return psImage    new image formed by rebinning input image.
+ */
+psImage* psImageRebin(
+    psImage* out,                      ///< an psImage to recycle.  If NULL, a new image is created
+    const psImage* in,                 ///< input image
+    const psImage* restrict mask,      ///< mask for input image.  If NULL, no masking is done.
+    psMaskType maskVal,                ///< the bits to check in mask.
+    unsigned int scale,                ///< the scale to rebin for each dimension
+    const psStats* stats
+    ///< the statistic to perform when rebinning.  Only one method should be set.
+);
+
+/** Resample image to new scale.
+ *
+ *  A new image is constructed in which the dimensions are increased by a 
+ *  factor of scale. The scale, always a positive number, is equal in each 
+ *  dimension. The output image is generated from all input image pixels. 
+ *  Each pixel in the output image is derived by interpolating between 
+ *  neighboring pixels using the specified interpolation method (mode).
+ *
+ *  @return psImage*    resampled image result
+ */
+psImage* psImageResample(
+    psImage* out,                      ///< an psImage to recycle.  If NULL, a new image is created
+    const psImage* in,                 ///< input image
+    int scale,                         ///< resample scaling factor
+    psImageInterpolateMode mode        ///< the interpolation mode used in resampling
+);
+
+/** Rotate the input image by given angle, specified in degrees.
+ *
+ *  The output image must contain all of the pixels from the input image in 
+ *  their new frame. Pixels in the output image which do not map to input 
+ *  pixels should be set to exposed. The center of rotation is always the 
+ *  center pixel of the image. The rotation is specified in the sense that a 
+ *  positive angle is an anti-clockwise rotation. This function must be 
+ *  defined for the following types: psU8, psU16, psS8, psS16, psF32, psF64, 
+ *  psC32, psC64.
+ *
+ *  @return psImage*     the rotated image result.
+ */
+psImage* psImageRotate(
+    psImage* out,                      ///< an psImage to recycle.  If NULL, a new image is created
+    const psImage* in,                 ///< input image
+    float angle,                       ///< the rotation angle in degrees.
+    psC64 unexposedValue,              ///< the output image pixel values for non-imagery areas
+    psImageInterpolateMode mode        ///< the interpolation mode used
+);
+
+/** Shift image by an arbitrary number of pixels (dx,dy) in either direction.
+ *
+ *  If the shift values are fractional, the output pixel values should 
+ *  interpolate between the input pixel values. The output image has the same 
+ *  dimensions as the input image. Pixels which fall off the edge of the 
+ *  output image are lost. Newly exposed pixels are set to the value given by 
+ *  exposed. This function must be defined for the following types: psU8, 
+ *  psU16, psS8, psS16, psF32, psF64, psC32, psC64.
+ *
+ *  @return psImage*     the shifted image result.
+ */
+psImage* psImageShift(
+    psImage* out,                      ///< an psImage to recycle.  If NULL, a new image is created
+    const psImage* in,                 ///< input image
+    float dx,                          ///< the shift in x direction.
+    float dy,                          ///< the shift in y direction.
+    psC64 unexposedValue,              ///< the output image pixel values for non-imagery areas
+    psImageInterpolateMode mode        ///< the interpolation mode to use
+);
+
+/** Roll image by an integer number of pixels in either direction.
+ * 
+ *  The output image is the same dimensions as the input image.  Edge pixels
+ *  wrap to the other side (no values are lost).  This function is 
+ *  defined for psU8, psS8, psS16, psF32, psF64, psC32, and psC64.
+ *
+ *  @return psImage* the rolled version of the input image.
+ */
+psImage* psImageRoll(
+    psImage* out,                      ///< an psImage to recycle.  If NULL, a new image is created
+    const psImage* in,                 ///< input image
+    int dx,                            ///< number of pixels to roll in the x-dimension
+    int dy                             ///< number of pixels to roll in the y-dimension
+);
+
+#endif
Index: /branches/rel3/psLib/src/image/psImageStats.c
===================================================================
--- /branches/rel3/psLib/src/image/psImageStats.c	(revision 2163)
+++ /branches/rel3/psLib/src/image/psImageStats.c	(revision 2163)
@@ -0,0 +1,450 @@
+/** @file psImageStats.c
+*  \brief Routines for calculating statistics on images.
+*  @ingroup ImageStats
+*
+*  This file will hold the prototypes for procedures which calculate
+*  statistic on images, histograms on images, and fit/evaluate Chebyshev
+*  polynomials to images.
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.43 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-14 01:06:44 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <float.h>
+#include <math.h>
+#include "psMemory.h"
+#include "psVector.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psStats.h"
+#include "psImage.h"
+#include "psFunctions.h"
+#include "psImageStats.h"
+#include "psConstants.h"
+
+#include "psImageErrors.h"
+
+/// This routine must determine the various statistics for the image.
+/*****************************************************************************
+XXX: verify that image/mask have the correct types, and sizes.
+ *****************************************************************************/
+psStats* psImageStats(psStats* stats,
+                      psImage* in,
+                      psImage* mask,
+                      int maskVal)
+{
+    psVector* junkData = NULL;
+    psVector* junkMask = NULL;
+
+    if (stats == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageStats",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_STAT_NULL);
+        return NULL;
+    }
+
+    if (in == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageStats",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        return NULL;
+    }
+
+    if (stats->options == 0) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageStats",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImage_NO_STAT_OPTIONS);
+        return stats;
+    }
+    // stuff the image data into a psVector struct.
+    junkData = psAlloc(sizeof(psVector));
+    junkData->type = in->type;
+    junkData->nalloc = in->numRows * in->numCols;
+    junkData->n = junkData->nalloc;
+    junkData->data.V = in->data.V[0];      // since psImage data is contiguous...
+
+    if (mask != NULL) {
+        if (mask->type.type != PS_TYPE_MASK) {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,mask->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageStats",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE,
+                       typeStr, PS_TYPE_MASK_NAME);
+            psFree(junkData);
+            return NULL;
+        }
+        // stuff the mask data into a psVector struct.
+        junkMask = psAlloc(sizeof(psVector));
+        junkMask->type = mask->type;
+        junkMask->nalloc = mask->numRows * mask->numCols;
+        junkMask->n = junkMask->nalloc;
+        junkMask->data.V = mask->data.V[0];
+    }
+
+    stats = psVectorStats(stats, junkData, junkMask, maskVal);
+
+    psFree(junkMask);
+    psFree(junkData);
+    return (stats);
+}
+
+/*****************************************************************************
+    NOTE: We assume that the psHistogram structure out has already been
+    allocated and initialized.
+    NOTE: verify that image/mask have the, correct types and  sizes.
+ *****************************************************************************/
+psHistogram* psImageHistogram(psHistogram* out,
+                              psImage* in,
+                              psImage* mask,
+                              unsigned int maskVal)
+{
+    psVector* junkData = NULL;
+    psVector* junkMask = NULL;
+
+    // NOTE: Verify this action.
+    PS_CHECK_NULL_PTR_RETURN_NULL(out);
+    PS_CHECK_NULL_PTR_RETURN_NULL(in);
+
+    junkData = psAlloc(sizeof(psVector));
+    junkData->type = in->type;
+    junkData->nalloc = in->numRows * in->numCols;
+    junkData->n = junkData->nalloc;
+    junkData->data.V = in->data.V[0];  // since psImage data is contiguous...
+
+    if (mask != NULL) {
+        if (mask->type.type != PS_TYPE_MASK) {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,mask->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageHistogram",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE,
+                       typeStr, PS_TYPE_MASK_NAME);
+            psFree(out);
+            psFree(junkData);
+            return NULL;
+        }
+        // stuff the mask data into a psVector struct.
+        junkMask = psAlloc(sizeof(psVector));
+        junkMask->type = mask->type;
+        junkMask->nalloc = mask->numRows * mask->numCols;
+        junkMask->n = junkMask->nalloc;
+        junkMask->data.V = mask->data.V[0];
+    }
+
+    out = psVectorHistogram(out, junkData, junkMask, maskVal);
+
+    psFree(junkMask);
+    psFree(junkData);
+
+    return (out);
+}
+
+// XXX: Why do we have this function?
+float *p_psCalcScaleFactorsFit(int n)
+{
+    int i = 0;
+    float tmp = 0.0;
+    float *scalingFactors = (float *)psAlloc(n * sizeof(float));
+
+    for (i = 0; i < n; i++) {
+        // ((2.0 * (float) i) / ((float) (n-1)))
+        // - 1.0;
+        // tmp = (float) (i + 1);
+        tmp = (float)(n - i);
+        tmp = (M_PI * (tmp - 0.5)) / ((float)n);
+        scalingFactors[i] = cos(tmp);
+    }
+
+    return (scalingFactors);
+}
+
+/*****************************************************************************
+p_psCalcScaleFactorsEval(n): The Chebyshev polynomials are defined over the
+interval [-1.0 : 1.0].  Images typically have sizes of 512x512 or more.  In
+order to use Chebyshev polynomials, we must scales the coordinates from
+0:512 to -1:1.  This routine takes as input an integer N and produces as
+output a vector of evenly spaced floating point values between -1.0:1.0.
+ *****************************************************************************/
+float *p_psCalcScaleFactorsEval(int n)
+{
+    int i = 0;
+    float tmp = 0.0;
+
+    return p_psCalcScaleFactorsFit(n);
+
+    printf("Should not get here\n");
+    float *scalingFactors = (float *)psAlloc(n * sizeof(float));
+
+    for (i = 0; i < n; i++) {
+        // scalingFactors[i] = ((2.0 * (float) i)
+        // / ((float) (n-1))) - 1.0;
+        tmp = (float)(n - i);
+        tmp = (M_PI * (tmp - 0.5)) / ((float)n);
+        scalingFactors[i] = cos(tmp);
+    }
+    return (scalingFactors);
+}
+
+// XXX: Use a static array of CHebyshev polynomials.
+psPolynomial1D **p_psCreateChebyshevPolys(int maxChebyPoly)
+{
+    if (maxChebyPoly < 1) {
+        return(NULL);
+    }
+    psPolynomial1D **chebPolys = NULL;
+    int i = 0;
+    int j = 0;
+
+    chebPolys = (psPolynomial1D **) psAlloc(maxChebyPoly * sizeof(psPolynomial1D *));
+    for (i = 0; i < maxChebyPoly; i++) {
+        chebPolys[i] = psPolynomial1DAlloc(i + 1, PS_POLYNOMIAL_ORD);
+    }
+
+    // Create the Chebyshev polynomials.
+    // Polynomial i has i-th order.
+    chebPolys[0]->coeff[0] = 1;
+    chebPolys[1]->coeff[1] = 1;
+    for (i = 2; i < maxChebyPoly; i++) {
+        for (j = 0; j < chebPolys[i - 1]->n; j++) {
+            chebPolys[i]->coeff[j + 1] = 2 * chebPolys[i - 1]->coeff[j];
+        }
+        for (j = 0; j < chebPolys[i - 2]->n; j++) {
+            chebPolys[i]->coeff[j] -= chebPolys[i - 2]->coeff[j];
+        }
+    }
+
+    return (chebPolys);
+}
+
+/*****************************************************************************
+psImageFitPolynomial(): This routine takes as input a 2-D image and produces
+as output the coefficients of the Chebyshev polynomials which match that
+input image.
+  Input:
+  Output:
+  Internal Data Structures:
+    chebPolys[i][j] 
+    sums[i][j]: This will contain the sum of 
+                input->data.F32[x][y] *
+                psPolynomial1DEval((float) x, chebPolys[i]) *
+                psPolynomial1DEval((float) y, chebPolys[j]);
+        over all pixels (x,y) in the image.
+ 
+XXX: Currently we only support F32.
+ *****************************************************************************/
+psPolynomial2D* psImageFitPolynomial(psPolynomial2D* coeffs,
+                                     const psImage* input)
+{
+    int x = 0;
+    int y = 0;
+    int i = 0;
+    int j = 0;
+    float **sums = NULL;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+    float *cScalingFactors = NULL;
+    float *rScalingFactors = NULL;
+
+    // Check for null inputs
+    if (input == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageFitPolynomial",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        return NULL;
+    }
+
+    if (coeffs == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageFitPolynomial",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_COEFF_NULL);
+        return NULL;
+    }
+
+    // Create the sums[][] data structure.  This
+    // will hold the LHS of
+    // equation
+    // 29 in the ADD: sums[k][l] = SUM {
+    // image(x,y) * Tk(x) * Tl(y) }
+    sums = (float **)psAlloc(coeffs->nX * sizeof(float *));
+    for (i = 0; i < coeffs->nX; i++) {
+        sums[i] = (float *)psAlloc(coeffs->nY * sizeof(float));
+    }
+    // We scale the pixel positions to values
+    // between -1.0 and 1.0
+    rScalingFactors = p_psCalcScaleFactorsFit(input->numRows);
+    cScalingFactors = p_psCalcScaleFactorsFit(input->numCols);
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = coeffs->nX;
+    if (coeffs->nY > coeffs->nX) {
+        maxChebyPoly = coeffs->nY;
+    }
+    chebPolys = p_psCreateChebyshevPolys(maxChebyPoly);
+
+
+    /*
+        // Sanity check for the Chebyshevs.
+        for (i = 0; i < coeffs->nX; i++) {
+            for (j = 0; j < coeffs->nY; j++) {
+                tmp = 0.0;
+                for (x = 0; x < input->numRows; x++) {
+                    tmp +=
+                        psPolynomial1DEval
+                        (rScalingFactors[x], chebPolys[i]) * psPolynomial1DEval(rScalingFactors[x], chebPolys[j]);
+     
+                }
+                // printf("SUM(Cheby(%d) * Cheby(%d))
+                // is %f\n", i, j, tmp);
+            }
+        }
+    */
+
+    // Compute the sums[][] data structure.
+    for (i = 0; i < coeffs->nX; i++) {
+        for (j = 0; j < coeffs->nY; j++) {
+            sums[i][j] = 0.0;
+            for (x = 0; x < input->numRows; x++) {
+                for (y = 0; y < input->numCols; y++) {
+                    sums[i][j] +=
+                        input->data.F32[x][y] *
+                        psPolynomial1DEval(rScalingFactors[x], chebPolys[i]) *
+                        psPolynomial1DEval(cScalingFactors[y], chebPolys[j]);
+                }
+            }
+        }
+    }
+
+    for (i = 0; i < coeffs->nX; i++) {
+        for (j = 0; j < coeffs->nY; j++) {
+            coeffs->coeff[i][j] = sums[i][j];
+            coeffs->coeff[i][j] /= (float)(input->numRows * input->numCols);
+
+            if ((i != 0) && (j != 0)) {
+                coeffs->coeff[i][j] *= 4.0;
+            } else if ((i == 0) && (j == 0)) {
+                coeffs->coeff[i][j] *= 1.0;
+            } else {
+                coeffs->coeff[i][j] *= 2.0;
+            }
+        }
+    }
+
+    // Free the Chebyshev polynomials that were
+    // created in this routine.
+    for (i = 0; i < maxChebyPoly; i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+
+    // Free some data
+    for (i = 0; i < coeffs->nX; i++) {
+        psFree(sums[i]);
+    }
+    psFree(sums);
+    psFree(cScalingFactors);
+    psFree(rScalingFactors);
+
+    return (coeffs);
+}
+
+/*****************************************************************************
+XXX: Use static variables for chebyshev polynomials and scaling factors. 
+ 
+XXX: Currently we only support F32.
+ *****************************************************************************/
+psImage* psImageEvalPolynomial(psImage* input, const psPolynomial2D* coeffs)
+{
+    int x = 0;
+    int y = 0;
+    int i = 0;
+    int j = 0;
+    //    float **sums = NULL;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+    float *cScalingFactors = NULL;
+    float *rScalingFactors = NULL;
+    float polySum = 0.0;
+
+    // Create the sums[][] data structure.  This will hold the LHS of
+    // equation 29 in the ADD:
+    //         sums[k][l] = SUM { image(x,y) * Tk(x) * Tl(y) }
+    //
+    //    sums = (float **)psAlloc(coeffs->nX * sizeof(float *));
+    //    for (i = 0; i < coeffs->nX; i++) {
+    //        sums[i] = (float *)psAlloc(coeffs->nY * sizeof(float));
+    //    }
+    //    for (i = 0; i < coeffs->nX; i++) {
+    //        for (j = 0; j < coeffs->nY; j++) {
+    //            sums[i][j] = 0.0;
+    //        }
+    //    }
+
+
+    // Check for null inputs
+    if (input == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageEvalPolynomial",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        return NULL;
+    }
+
+    if (coeffs == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageEvalPolynomial",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_COEFF_NULL);
+        return NULL;
+    }
+
+    // We scale the pixel positions to values between -1.0 and 1.0
+    // Use static data structures here.
+    rScalingFactors = p_psCalcScaleFactorsEval(input->numRows);
+    cScalingFactors = p_psCalcScaleFactorsEval(input->numCols);
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = coeffs->nX;
+    if (coeffs->nY > coeffs->nX) {
+        maxChebyPoly = coeffs->nY;
+    }
+
+    chebPolys = p_psCreateChebyshevPolys(maxChebyPoly);
+
+    for (x = 0; x < input->numRows; x++) {
+        for (y = 0; y < input->numCols; y++) {
+            polySum = 0.0;
+            for (i = 0; i < coeffs->nX; i++) {
+                for (j = 0; j < coeffs->nY; j++) {
+                    polySum +=
+                        psPolynomial1DEval(rScalingFactors[x], chebPolys[i]) *
+                        psPolynomial1DEval(cScalingFactors[y], chebPolys[j]) *
+                        coeffs->coeff[i][j];
+
+                }
+            }
+            input->data.F32[x][y] = polySum;
+        }
+    }
+
+    // Free the Chebyshev polynomials that were
+    // created in this routine.
+    // XXX: Use dtatic data structures here.
+    for (i = 0; i < maxChebyPoly; i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+
+    psFree(cScalingFactors);
+    psFree(rScalingFactors);
+
+    return input;
+}
Index: /branches/rel3/psLib/src/image/psImageStats.h
===================================================================
--- /branches/rel3/psLib/src/image/psImageStats.h	(revision 2163)
+++ /branches/rel3/psLib/src/image/psImageStats.h	(revision 2163)
@@ -0,0 +1,89 @@
+/** @file psImageStats.h
+*  \brief Routines for calculating statistics on images.
+*  @ingroup ImageStats
+*
+*  This file will hold the prototypes for procedures which calculate
+*  statistic on images, histograms on images, and fit/evaluate Chebyshev
+*  polynomials to images.
+*
+*  @author George Gusciora, MHPCC
+*
+*  @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-05 01:03:11 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#if !defined(PS_IMAGE_STATS_H)
+#define PS_IMAGE_STATS_H
+
+#include "psType.h"
+#include "psVector.h"
+#include "psImage.h"
+#include "psStats.h"
+#include "psFunctions.h"
+
+/// @addtogroup ImageStats
+/// @{
+
+/** This routine must determine the various statistics for the image.
+ *
+ *  Determine statistics for image (or subimage). The statistics to be 
+ *  determined are specified by stats. The mask allows pixels to be excluded 
+ *  if their corresponding mask pixel value matches the value of maskVal. 
+ *  This function must be defined for the following types: psS8, psU16, psF32, 
+ *  psF64.
+ *
+ *  @return psStats*    the resulting statistics result(s)
+ */
+psStats* psImageStats(
+    psStats* stats,                    ///< defines statistics to be calculated
+    psImage* in,                       ///< image (or subimage) to calculate stats
+    psImage* mask,                     ///< mask data for image (NULL ok)
+    int maskVal                        ///< mask Mask for mask
+);
+
+/** Construct a histogram from an image (or subimage).
+ *
+ *  The histogram to generate is specified by psHistogram hist (see section 
+ *  4.3.2 in SDRS). This function must be defined for the following types: 
+ *  psS8, psU16, psF32, psF64.
+ *
+ *  @return psHistogram*     the resulting histogram
+ */
+psHistogram* psImageHistogram(
+    psHistogram* out,                  ///< input histogram description & target
+    psImage* in,                       ///< Image data to be histogramed.
+    psImage* mask,                     ///< mask data for image (NULL ok)
+    unsigned int maskVal               ///< mask Mask for mask
+);
+
+/** Fit a 2-D polynomial surface to an image.
+ *
+ *  The input structure coeffs contains the desired order and terms of 
+ *  interest. This function must be defined for the following types: psS8, 
+ *  psU16, psF32, psF64.
+ *
+ *  @return psPolynomial2D*     fitted polynomial result
+ *
+ */
+psPolynomial2D* psImageFitPolynomial(
+    psPolynomial2D* coeffs,            ///< coefficient structure carries in desired terms & target
+    const psImage* input
+);
+
+/** Evaluate a 2-D polynomial surface for the image pixels.
+ *
+ *  Given the input polynomial coefficients, set the image pixel values on the 
+ *  basis of the polynomial function. This function must be defined for the 
+ *  following types: psS8, psU16, psF32, psF64.
+ *
+ *  @return psImage*    the resulting image
+ */
+psImage* psImageEvalPolynomial(
+    psImage* input,                    ///< input image
+    const psPolynomial2D* coeffs       ///< coefficient structure carries in desired terms
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/imageops/psImageConvolve.c
===================================================================
--- /branches/rel3/psLib/src/imageops/psImageConvolve.c	(revision 2163)
+++ /branches/rel3/psLib/src/imageops/psImageConvolve.c	(revision 2163)
@@ -0,0 +1,437 @@
+/*  @file  psImageConvolve.c
+ *
+ *  @brief Contains FFT transform related functions for psImage.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-06 21:31:30 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <string.h>
+
+#include "psImageConvolve.h"
+#include "psImageFFT.h"
+#include "psImageExtraction.h"
+#include "psMatrixVectorArithmetic.h"
+#include "psMemory.h"
+#include "psLogMsg.h"
+#include "psError.h"
+#include "psImageIO.h"
+
+#include "psImageErrors.h"
+
+#define FOURIER_PADDING 32 /* padding amount in every side of the image for fourier convolution */
+
+static void freeKernel(psKernel* ptr);
+
+psKernel* psKernelAlloc(int xMin, int xMax, int yMin, int yMax)
+{
+    psKernel* result;
+    int numRows;
+    int numCols;
+
+    // following is explicitly spelled out in the SDRS as a requirement
+    if (yMin > yMax) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "Specified yMin, %d, was greater than yMax, %d.  Values swapped.",
+                 yMin, yMax);
+
+        int temp = yMin;
+        yMin = yMax;
+        yMax = temp;
+    }
+
+    // following is explicitly spelled out in the SDRS as a requirement
+    if (xMin > xMax) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "Specified xMin, %d, was greater than xMax, %d.  Values swapped.",
+                 xMin, xMax);
+
+        int temp = xMin;
+        xMin = xMax;
+        xMax = temp;
+    }
+
+    numRows = yMax - yMin + 1;
+    numCols = xMax - xMin + 1;
+
+    result = psAlloc(sizeof(psKernel));
+    result->xMin = xMin;
+    result->xMax = xMax;
+    result->yMin = yMin;
+    result->yMax = yMax;
+    result->image = psImageAlloc(numCols,numRows,PS_TYPE_KERNEL);
+    memset(result->image->rawDataBuffer,0,numCols*numRows*PSELEMTYPE_SIZEOF(PS_TYPE_KERNEL));
+    result->p_kernelRows = psAlloc(sizeof(psKernelType*)*numRows);
+
+    psKernelType** kernelRows = result->p_kernelRows;
+    psKernelType** imageRows = result->image->data.PS_TYPE_KERNEL_DATA;
+    for (int i = 0; i < numRows; i++) {
+        kernelRows[i] = imageRows[i] - xMin;
+    }
+    result->kernel = kernelRows - yMin;
+
+    p_psMemSetDeallocator(result,(psFreeFcn)freeKernel);
+
+    return result;
+}
+
+void freeKernel(psKernel* ptr)
+{
+    if (ptr != NULL) {
+        psFree(ptr->image);
+        psFree(ptr->p_kernelRows);
+    }
+}
+
+psKernel* psKernelGenerate(const psVector* tShifts,
+                           const psVector* xShifts,
+                           const psVector* yShifts,
+                           bool relative)
+{
+    int x = 0;
+    int y = 0;
+    int t = 0;
+    int deltaT;
+    int oldX;
+    int oldY;
+    int xMin = 0;
+    int xMax = 0;
+    int yMin = 0;
+    int yMax = 0;
+    int length = 0;
+    psKernelType normalizeTime = 1.0;  // fraction of total time for each shift clock
+    psKernel* result = NULL;
+    psKernelType** kernel = NULL;
+
+    // got non-NULL vectors?
+    if (tShifts == NULL || xShifts == NULL || yShifts == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psKernelGenerate",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImageConvolve_SHIFT_NULL);
+        return NULL;
+    }
+
+    // types match?
+    if (xShifts->type.type != yShifts->type.type ||
+            tShifts->type.type != xShifts->type.type) {
+        char* typeXStr;
+        char* typeYStr;
+        char* typeTStr;
+        PS_TYPE_NAME(typeXStr,xShifts->type.type);
+        PS_TYPE_NAME(typeYStr,yShifts->type.type);
+        PS_TYPE_NAME(typeTStr,tShifts->type.type);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psKernelGenerate",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImageConvolve_SHIFT_TYPE_MISMATCH,
+                   typeTStr, typeXStr, typeYStr);
+        return NULL;
+    }
+
+    // determine the usable length of the shift vector
+    length = xShifts->n;
+    if (length != yShifts->n ||
+            length != tShifts->n) {
+        psLogMsg(__func__,PS_LOG_WARN,"Shift vectors found to be different sizes.");
+        if (yShifts->n < length) {
+            length = yShifts->n;
+        }
+        if (tShifts->n < length) {
+            length = tShifts->n;
+        }
+    }
+
+    #define KERNEL_GENERATE_CASE(TYPE) \
+case PS_TYPE_##TYPE: { \
+        ps##TYPE *tShiftData = tShifts->data.TYPE; \
+        ps##TYPE *xShiftData = xShifts->data.TYPE; \
+        ps##TYPE *yShiftData = yShifts->data.TYPE; \
+        x = 0; \
+        y = 0; \
+        t = 0; \
+        for (int lcv = 0; lcv < length; lcv++) { \
+            if (relative) { \
+                x += xShiftData[lcv]; \
+                y += yShiftData[lcv]; \
+                t += tShiftData[lcv]; \
+            } else { \
+                x = xShiftData[lcv]; \
+                y = yShiftData[lcv]; \
+                t = tShiftData[lcv]; \
+            } \
+            if (x < xMin) { \
+                xMin = x; \
+            } else if (x > xMax) { \
+                xMax = x; \
+            } \
+            if (y < yMin) { \
+                yMin = y; \
+            } else if (y > yMax) { \
+                yMax = y; \
+            } \
+        } \
+        result = psKernelAlloc(xMin,xMax,yMin,yMax); \
+        kernel = result->kernel; \
+        \
+        normalizeTime = 1.0 / (psKernelType)(t); \
+        x = 0; \
+        y = 0; \
+        t = 0; \
+        for (int i = 0; i < length; i++) { \
+            deltaT = t; \
+            oldX = x; \
+            oldY = y; \
+            if (relative) { \
+                t += tShiftData[i]; \
+                x += xShiftData[i]; \
+                y += yShiftData[i]; \
+            } else { \
+                t = tShiftData[i]; \
+                x = xShiftData[i]; \
+                y = yShiftData[i]; \
+            } \
+            deltaT = t - deltaT; \
+            \
+            kernel[oldY][oldX] += deltaT * normalizeTime; \
+        } \
+        break; \
+    }
+
+    switch (xShifts->type.type) {
+        KERNEL_GENERATE_CASE(U8);
+        KERNEL_GENERATE_CASE(U16);
+        KERNEL_GENERATE_CASE(U32);
+        KERNEL_GENERATE_CASE(U64);
+        KERNEL_GENERATE_CASE(S8);
+        KERNEL_GENERATE_CASE(S16);
+        KERNEL_GENERATE_CASE(S32);
+        KERNEL_GENERATE_CASE(S64);
+        KERNEL_GENERATE_CASE(F32);
+        KERNEL_GENERATE_CASE(F64);
+        KERNEL_GENERATE_CASE(C32);
+        KERNEL_GENERATE_CASE(C64);
+
+    default: {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,xShifts->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psKernelGenerate",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                       typeStr);
+        }
+    }
+
+    return result;
+}
+
+psImage* psImageConvolve(psImage* out, const psImage* in, const psKernel* kernel, bool direct)
+{
+    if (in == NULL) {
+        psFree(out);
+        return NULL;
+    }
+
+    if (kernel == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageConvolve",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImageConvolve_KERNEL_NULL);
+        psFree(out);
+        return NULL;
+    }
+    int xMin = kernel->xMin;
+    int xMax = kernel->xMax;
+    int yMin = kernel->yMin;
+    int yMax = kernel->yMax;
+    psKernelType** kData = kernel->kernel;
+
+    // make the output image to the proper size and type
+    int numRows = in->numRows;
+    int numCols = in->numCols;
+
+
+
+    if (direct) {
+        // spatial convolution
+
+        #define SPATIAL_CONVOLVE_CASE(TYPE) \
+    case PS_TYPE_##TYPE: { \
+            ps##TYPE** inData = in->data.TYPE; \
+            out = psImageRecycle(out, numCols, numRows, PS_TYPE_##TYPE); \
+            for (int row=0;row<numRows;row++) { \
+                ps##TYPE* outRow = out->data.TYPE[row]; \
+                for (int col=0;col<numCols;col++) { \
+                    ps##TYPE pixel = 0.0; \
+                    for (int kRow = yMin; kRow < yMax; kRow++) { \
+                        if (row-kRow >= 0 && row-kRow < numRows) { \
+                            for (int kCol = xMin; kCol < xMax; kCol++) { \
+                                if (col-kCol >= 0 && col-kCol < numCols) { \
+                                    pixel += kData[kRow][kCol] * inData[row-kRow][col-kCol]; \
+                                } \
+                            } \
+                        } \
+                    } \
+                    outRow[col] = pixel; \
+                } \
+            } \
+        } \
+        break;
+
+        switch (in->type.type) {
+            SPATIAL_CONVOLVE_CASE(U8)
+            SPATIAL_CONVOLVE_CASE(U16)
+            SPATIAL_CONVOLVE_CASE(U32)
+            SPATIAL_CONVOLVE_CASE(U64)
+            SPATIAL_CONVOLVE_CASE(S8)
+            SPATIAL_CONVOLVE_CASE(S16)
+            SPATIAL_CONVOLVE_CASE(S32)
+            SPATIAL_CONVOLVE_CASE(S64)
+            SPATIAL_CONVOLVE_CASE(F32)
+            SPATIAL_CONVOLVE_CASE(F64)
+            SPATIAL_CONVOLVE_CASE(C32)
+            SPATIAL_CONVOLVE_CASE(C64)
+
+        default: {
+                char* typeStr;
+                PS_TYPE_NAME(typeStr,in->type.type);
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageConvolve",
+                           PS_ERR_BAD_PARAMETER_TYPE, true,
+                           PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                           typeStr);
+                psFree(out);
+                return NULL;
+
+            }
+        }
+
+
+    } else {
+        // fourier convolution
+        int paddedCols = numCols+2*FOURIER_PADDING;
+        int paddedRows = numRows+2*FOURIER_PADDING;
+
+        // check to see if kernel is smaller, otherwise padding it up will fail.
+        int kRows = kernel->image->numRows;
+        int kCols = kernel->image->numCols;
+        if (kRows >= numRows || kCols >= numCols) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageConvolve",
+                       PS_ERR_BAD_PARAMETER_SIZE, true,
+                       PS_ERRORTEXT_psImageConvolve_KERNEL_TOO_LARGE,
+                       kCols,kRows,
+                       numCols, numRows);
+            psFree(out);
+            return NULL;
+        }
+
+        // pad the image
+        psImage* paddedImage = psImageAlloc(paddedCols,paddedRows,in->type.type);
+        int elementSize = PSELEMTYPE_SIZEOF(in->type.type);
+
+        // zero out padded area on top and bottom
+        memset(paddedImage->data.U8[0],0,FOURIER_PADDING*paddedCols*elementSize);
+        memset(paddedImage->data.U8[FOURIER_PADDING+numRows-1],0,FOURIER_PADDING*paddedCols*elementSize);
+
+        // fill in the image-containing rows.
+        int sidePaddingSize = FOURIER_PADDING*elementSize;
+        int imageRowSize = numCols*elementSize;
+        psU8* paddedData = paddedImage->data.U8[FOURIER_PADDING];
+        for (int row=0;row<numRows;row++) {
+            // zero out padded area on left edge.
+            memset(paddedData,0,sidePaddingSize);
+            paddedData += sidePaddingSize;
+            memcpy(paddedData,in->data.U8[row],imageRowSize);
+            paddedData += imageRowSize;
+            // zero out padded area on right edge.
+            memset(paddedData,0,sidePaddingSize);
+            paddedData += sidePaddingSize;
+        }
+
+        psImageWriteSection(paddedImage,0,0,0,NULL,0,"paddedImage.fits");
+
+        // pad the kernel to the same size of paddedImage
+        psImage* paddedKernel = psImageAlloc(paddedCols,paddedRows,PS_TYPE_KERNEL);
+        memset(paddedKernel->data.U8[0],0,sizeof(psKernelType)*numCols*numRows); // zero-out image
+        int yMax = kernel->yMax;
+        int xMax = kernel->xMax;
+        for (int row = kernel->yMin; row <= yMax;row++) {
+            int padRow = row;
+            if (padRow < 0) {
+                padRow += paddedRows;
+            }
+            psKernelType* padData = paddedKernel->data.PS_TYPE_KERNEL_DATA[padRow];
+            psKernelType* kernelRow = kernel->kernel[row];
+            for (int col = kernel->xMin; col <= xMax; col++) {
+                if (col < 0) {
+                    padData[col+paddedCols] = kernelRow[col];
+                } else {
+                    padData[col] = kernelRow[col];
+                }
+            }
+        }
+
+        psImageWriteSection(paddedKernel,0,0,0,NULL,0,"paddedKernel.fits");
+
+        psImage* kernelFourier = psImageFFT(NULL, paddedKernel, PS_FFT_FORWARD);
+        if (kernelFourier == NULL) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageConvolve",
+                       PS_ERR_UNKNOWN, false,
+                       PS_ERRORTEXT_psImageConvolve_KERNEL_FFT_FAILED);
+            psFree(out);
+            return NULL;
+        }
+
+        psImage* inFourier = psImageFFT(NULL, paddedImage, PS_FFT_FORWARD);
+        if (inFourier == NULL) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageConvolve",
+                       PS_ERR_UNKNOWN, false,
+                       PS_ERRORTEXT_psImageConvolve_FFT_FAILED);
+            psFree(out);
+            return NULL;
+        }
+
+        // convolution in fourier domain is just a pixel-wise multiplication
+        psBinaryOp(inFourier,inFourier,"*",kernelFourier);
+
+        psImage* complexOut = psImageFFT(NULL, inFourier,
+                                         PS_FFT_REVERSE);
+        if (complexOut == NULL) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageConvolve",
+                       PS_ERR_UNKNOWN, false,
+                       PS_ERRORTEXT_psImageConvolve_FFT_FAILED);
+            psFree(out);
+            return NULL;
+        }
+
+        {
+            psImage* tmp = psImageReal(NULL,complexOut);
+            psImageWriteSection(tmp,0,0,0,NULL,0,"complexOut.fits");
+            psFree(tmp);
+        }
+
+        // subset out the padded area now.
+        psImage* complexOutSansPad = psImageSubset(complexOut,
+                                     FOURIER_PADDING,FOURIER_PADDING,
+                                     FOURIER_PADDING+numCols,FOURIER_PADDING+numRows);
+
+        out = psImageRecycle(out,numCols,numRows,PS_TYPE_F32);
+        float factor = 1.0f/numCols/numRows;
+        for (int row = 0; row < numRows; row++) {
+            psF32* outRow = out->data.F32[row];
+            psC32* resultRow = complexOutSansPad->data.C32[row];
+            for (int col = 0; col < numCols; col++) {
+                outRow[col] = crealf(resultRow[col])*factor;
+            }
+        }
+
+        psFree(complexOut); // frees complexOutSansPad, as it is a child.
+        psFree(kernelFourier);
+        psFree(inFourier);
+        psFree(paddedImage);
+        psFree(paddedKernel);
+
+    }
+
+    return out;
+}
Index: /branches/rel3/psLib/src/imageops/psImageConvolve.h
===================================================================
--- /branches/rel3/psLib/src/imageops/psImageConvolve.h	(revision 2163)
+++ /branches/rel3/psLib/src/imageops/psImageConvolve.h	(revision 2163)
@@ -0,0 +1,123 @@
+/** @file  psImageConvolve.h
+ *
+ *  @brief image convolution functionality
+ *
+ *  @ingroup Transform
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-23 18:30:57 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_IMAGE_CONVOLVE_H
+#define PS_IMAGE_CONVOLVE_H
+
+#include<stdbool.h>
+
+#include "psImage.h"
+#include "psVector.h"
+#include "psType.h"
+
+#define PS_TYPE_KERNEL PS_TYPE_F32     /**< the data member to use for kernel image */
+#define PS_TYPE_KERNEL_DATA F32        /**< the data member to use for kernel image */
+#define PS_TYPE_KERNEL_NAME "psF32"    /**< the data type for kernel as a string */
+
+typedef psF32 psKernelType;
+
+/** A convolution kernel */
+typedef struct
+{
+    psImage* image;                    ///< Kernel data, in the form of an image
+    int xMin;                          ///< Most negative x index
+    int yMin;                          ///< Most negative y index
+    int xMax;                          ///< Most positive x index
+    int yMax;                          ///< Most positive y index
+    psKernelType** kernel;             ///< Pointer to the kernel data
+    psKernelType** p_kernelRows;       ///< Pointer to the rows of the kernel data; not intended for user use.
+}
+psKernel;
+
+/** Allocates a convolution kernel of the given range
+ *
+ *  In order to perform a convolution, we need to define the convolution 
+ *  kernel. We need a more general object than a psImage so that we can 
+ *  incorporate the offset from the (0, 0) pixel to the (0, 0) value of the 
+ *  kernel. It might be convenient to allow both positive and negative 
+ *  indices to convey the positive and negative shifts. One might consider 
+ *  setting the x0 and y0 members of a psImage to the appropriate offsets, 
+ *  but this is not the purpose of these members, and doing so may affect the 
+ *  behavior of other psImage operations.
+ *
+ *  This construction allows the kernel member to use negative indices, while 
+ *  preserving the location of psMemBlocks relative to allocated memory.
+ *
+ *  The maximum extent of the kernel shifts shall be defined by the xMin, 
+ *  xMax, yMin and yMax members. Note that xMin and yMin, under normal 
+ *  circumstances, should be negative numbers. That is, 
+ *  myKernel->kernel[-3][-2] may be defined if yMin and xMin are equal to or 
+ *  more negative than -3 and -2, respectively.
+ *
+ *  In the event that one of the minimum values is greater than the 
+ *  corresponding maximum value, the function shall generate a warning, and 
+ *  the offending values shall be exchanged.
+ *
+ *  @return psKernel*          A new kernel object
+ */
+psKernel* psKernelAlloc(
+    int xMin,                          ///< Most negative x index
+    int xMax,                          ///< Most positive x index
+    int yMin,                          ///< Most negative y index
+    int yMax                           ///< Most positive y index
+);
+
+/** Generates a kernel given a list of shift values
+ *
+ *  Given a list of values (e.g., shifts made in the course of OT guiding), 
+ *  psKernelGenerate shall return the appropriate kernel.  The vectors xShifts 
+ *  and yShifts, which are a list of shifts relative to some starting point, 
+ *  will be supplied by the user. The elements of the vectors should be of an 
+ *  integer type; otherwise the values shall be truncated to integers. The 
+ *  output kernel shall be normalized such that the sum over the kernel is 
+ *  unity. 
+ *
+ *  If the vectors are not of the same number of elements, then the function 
+ *  shall generate a warning shall be generated, following which, the longer 
+ *  vector trimmed to the length of the shorter, and the function shall continue.
+ *
+ *  @return psKernel*    new Kernel object
+ */
+psKernel* psKernelGenerate(
+    const psVector* tShifts,           ///< list of time shifts
+    const psVector* xShifts,           ///< list of x-axis shifts
+    const psVector* yShifts,           ///< list of y-axis shifts
+    bool relative
+);
+
+/** convolve an image with a kernel
+ *
+ *  Given an input image and the convolution kernel, psImageConvolve shall 
+ *  convolve the input image, in, with the kernel, kernel and return the 
+ *  convolved image, out.
+ * 
+ *  Two methods shall be available for the convolution: if direct is true, 
+ *  then the convolution shall be performed in real space (appropriate for 
+ *  small kernels); otherwise, the convolution shall be performed using Fast 
+ *  Fourier Transforms (FFTs; appropriate for larger kernels). The latter 
+ *  option involves padding the input image, copying the kernel into an image 
+ *  of the same size as the padded input image, performing an FFT on each, 
+ *  multiplying the FFTs, and performing an inverse FFT before trimming the 
+ *  image back to the original size.
+ *
+ *  @return psImage*  resulting image 
+ */
+psImage* psImageConvolve(
+    psImage* out,                      ///< a psImage to recycle.  If NULL, a new psImage is made.
+    const psImage* in,                 ///< the psImage to convolve
+    const psKernel* kernel,            ///< kernel to colvolve with
+    bool direct                        ///< specifies method, true=direct convolution, false=fourier
+);
+
+#endif
Index: /branches/rel3/psLib/src/imageops/psImageStats.c
===================================================================
--- /branches/rel3/psLib/src/imageops/psImageStats.c	(revision 2163)
+++ /branches/rel3/psLib/src/imageops/psImageStats.c	(revision 2163)
@@ -0,0 +1,450 @@
+/** @file psImageStats.c
+*  \brief Routines for calculating statistics on images.
+*  @ingroup ImageStats
+*
+*  This file will hold the prototypes for procedures which calculate
+*  statistic on images, histograms on images, and fit/evaluate Chebyshev
+*  polynomials to images.
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.43 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-14 01:06:44 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <float.h>
+#include <math.h>
+#include "psMemory.h"
+#include "psVector.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psStats.h"
+#include "psImage.h"
+#include "psFunctions.h"
+#include "psImageStats.h"
+#include "psConstants.h"
+
+#include "psImageErrors.h"
+
+/// This routine must determine the various statistics for the image.
+/*****************************************************************************
+XXX: verify that image/mask have the correct types, and sizes.
+ *****************************************************************************/
+psStats* psImageStats(psStats* stats,
+                      psImage* in,
+                      psImage* mask,
+                      int maskVal)
+{
+    psVector* junkData = NULL;
+    psVector* junkMask = NULL;
+
+    if (stats == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageStats",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_STAT_NULL);
+        return NULL;
+    }
+
+    if (in == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageStats",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        return NULL;
+    }
+
+    if (stats->options == 0) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageStats",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImage_NO_STAT_OPTIONS);
+        return stats;
+    }
+    // stuff the image data into a psVector struct.
+    junkData = psAlloc(sizeof(psVector));
+    junkData->type = in->type;
+    junkData->nalloc = in->numRows * in->numCols;
+    junkData->n = junkData->nalloc;
+    junkData->data.V = in->data.V[0];      // since psImage data is contiguous...
+
+    if (mask != NULL) {
+        if (mask->type.type != PS_TYPE_MASK) {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,mask->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageStats",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE,
+                       typeStr, PS_TYPE_MASK_NAME);
+            psFree(junkData);
+            return NULL;
+        }
+        // stuff the mask data into a psVector struct.
+        junkMask = psAlloc(sizeof(psVector));
+        junkMask->type = mask->type;
+        junkMask->nalloc = mask->numRows * mask->numCols;
+        junkMask->n = junkMask->nalloc;
+        junkMask->data.V = mask->data.V[0];
+    }
+
+    stats = psVectorStats(stats, junkData, junkMask, maskVal);
+
+    psFree(junkMask);
+    psFree(junkData);
+    return (stats);
+}
+
+/*****************************************************************************
+    NOTE: We assume that the psHistogram structure out has already been
+    allocated and initialized.
+    NOTE: verify that image/mask have the, correct types and  sizes.
+ *****************************************************************************/
+psHistogram* psImageHistogram(psHistogram* out,
+                              psImage* in,
+                              psImage* mask,
+                              unsigned int maskVal)
+{
+    psVector* junkData = NULL;
+    psVector* junkMask = NULL;
+
+    // NOTE: Verify this action.
+    PS_CHECK_NULL_PTR_RETURN_NULL(out);
+    PS_CHECK_NULL_PTR_RETURN_NULL(in);
+
+    junkData = psAlloc(sizeof(psVector));
+    junkData->type = in->type;
+    junkData->nalloc = in->numRows * in->numCols;
+    junkData->n = junkData->nalloc;
+    junkData->data.V = in->data.V[0];  // since psImage data is contiguous...
+
+    if (mask != NULL) {
+        if (mask->type.type != PS_TYPE_MASK) {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,mask->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageHistogram",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_MASK_TYPE,
+                       typeStr, PS_TYPE_MASK_NAME);
+            psFree(out);
+            psFree(junkData);
+            return NULL;
+        }
+        // stuff the mask data into a psVector struct.
+        junkMask = psAlloc(sizeof(psVector));
+        junkMask->type = mask->type;
+        junkMask->nalloc = mask->numRows * mask->numCols;
+        junkMask->n = junkMask->nalloc;
+        junkMask->data.V = mask->data.V[0];
+    }
+
+    out = psVectorHistogram(out, junkData, junkMask, maskVal);
+
+    psFree(junkMask);
+    psFree(junkData);
+
+    return (out);
+}
+
+// XXX: Why do we have this function?
+float *p_psCalcScaleFactorsFit(int n)
+{
+    int i = 0;
+    float tmp = 0.0;
+    float *scalingFactors = (float *)psAlloc(n * sizeof(float));
+
+    for (i = 0; i < n; i++) {
+        // ((2.0 * (float) i) / ((float) (n-1)))
+        // - 1.0;
+        // tmp = (float) (i + 1);
+        tmp = (float)(n - i);
+        tmp = (M_PI * (tmp - 0.5)) / ((float)n);
+        scalingFactors[i] = cos(tmp);
+    }
+
+    return (scalingFactors);
+}
+
+/*****************************************************************************
+p_psCalcScaleFactorsEval(n): The Chebyshev polynomials are defined over the
+interval [-1.0 : 1.0].  Images typically have sizes of 512x512 or more.  In
+order to use Chebyshev polynomials, we must scales the coordinates from
+0:512 to -1:1.  This routine takes as input an integer N and produces as
+output a vector of evenly spaced floating point values between -1.0:1.0.
+ *****************************************************************************/
+float *p_psCalcScaleFactorsEval(int n)
+{
+    int i = 0;
+    float tmp = 0.0;
+
+    return p_psCalcScaleFactorsFit(n);
+
+    printf("Should not get here\n");
+    float *scalingFactors = (float *)psAlloc(n * sizeof(float));
+
+    for (i = 0; i < n; i++) {
+        // scalingFactors[i] = ((2.0 * (float) i)
+        // / ((float) (n-1))) - 1.0;
+        tmp = (float)(n - i);
+        tmp = (M_PI * (tmp - 0.5)) / ((float)n);
+        scalingFactors[i] = cos(tmp);
+    }
+    return (scalingFactors);
+}
+
+// XXX: Use a static array of CHebyshev polynomials.
+psPolynomial1D **p_psCreateChebyshevPolys(int maxChebyPoly)
+{
+    if (maxChebyPoly < 1) {
+        return(NULL);
+    }
+    psPolynomial1D **chebPolys = NULL;
+    int i = 0;
+    int j = 0;
+
+    chebPolys = (psPolynomial1D **) psAlloc(maxChebyPoly * sizeof(psPolynomial1D *));
+    for (i = 0; i < maxChebyPoly; i++) {
+        chebPolys[i] = psPolynomial1DAlloc(i + 1, PS_POLYNOMIAL_ORD);
+    }
+
+    // Create the Chebyshev polynomials.
+    // Polynomial i has i-th order.
+    chebPolys[0]->coeff[0] = 1;
+    chebPolys[1]->coeff[1] = 1;
+    for (i = 2; i < maxChebyPoly; i++) {
+        for (j = 0; j < chebPolys[i - 1]->n; j++) {
+            chebPolys[i]->coeff[j + 1] = 2 * chebPolys[i - 1]->coeff[j];
+        }
+        for (j = 0; j < chebPolys[i - 2]->n; j++) {
+            chebPolys[i]->coeff[j] -= chebPolys[i - 2]->coeff[j];
+        }
+    }
+
+    return (chebPolys);
+}
+
+/*****************************************************************************
+psImageFitPolynomial(): This routine takes as input a 2-D image and produces
+as output the coefficients of the Chebyshev polynomials which match that
+input image.
+  Input:
+  Output:
+  Internal Data Structures:
+    chebPolys[i][j] 
+    sums[i][j]: This will contain the sum of 
+                input->data.F32[x][y] *
+                psPolynomial1DEval((float) x, chebPolys[i]) *
+                psPolynomial1DEval((float) y, chebPolys[j]);
+        over all pixels (x,y) in the image.
+ 
+XXX: Currently we only support F32.
+ *****************************************************************************/
+psPolynomial2D* psImageFitPolynomial(psPolynomial2D* coeffs,
+                                     const psImage* input)
+{
+    int x = 0;
+    int y = 0;
+    int i = 0;
+    int j = 0;
+    float **sums = NULL;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+    float *cScalingFactors = NULL;
+    float *rScalingFactors = NULL;
+
+    // Check for null inputs
+    if (input == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageFitPolynomial",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        return NULL;
+    }
+
+    if (coeffs == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageFitPolynomial",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_COEFF_NULL);
+        return NULL;
+    }
+
+    // Create the sums[][] data structure.  This
+    // will hold the LHS of
+    // equation
+    // 29 in the ADD: sums[k][l] = SUM {
+    // image(x,y) * Tk(x) * Tl(y) }
+    sums = (float **)psAlloc(coeffs->nX * sizeof(float *));
+    for (i = 0; i < coeffs->nX; i++) {
+        sums[i] = (float *)psAlloc(coeffs->nY * sizeof(float));
+    }
+    // We scale the pixel positions to values
+    // between -1.0 and 1.0
+    rScalingFactors = p_psCalcScaleFactorsFit(input->numRows);
+    cScalingFactors = p_psCalcScaleFactorsFit(input->numCols);
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = coeffs->nX;
+    if (coeffs->nY > coeffs->nX) {
+        maxChebyPoly = coeffs->nY;
+    }
+    chebPolys = p_psCreateChebyshevPolys(maxChebyPoly);
+
+
+    /*
+        // Sanity check for the Chebyshevs.
+        for (i = 0; i < coeffs->nX; i++) {
+            for (j = 0; j < coeffs->nY; j++) {
+                tmp = 0.0;
+                for (x = 0; x < input->numRows; x++) {
+                    tmp +=
+                        psPolynomial1DEval
+                        (rScalingFactors[x], chebPolys[i]) * psPolynomial1DEval(rScalingFactors[x], chebPolys[j]);
+     
+                }
+                // printf("SUM(Cheby(%d) * Cheby(%d))
+                // is %f\n", i, j, tmp);
+            }
+        }
+    */
+
+    // Compute the sums[][] data structure.
+    for (i = 0; i < coeffs->nX; i++) {
+        for (j = 0; j < coeffs->nY; j++) {
+            sums[i][j] = 0.0;
+            for (x = 0; x < input->numRows; x++) {
+                for (y = 0; y < input->numCols; y++) {
+                    sums[i][j] +=
+                        input->data.F32[x][y] *
+                        psPolynomial1DEval(rScalingFactors[x], chebPolys[i]) *
+                        psPolynomial1DEval(cScalingFactors[y], chebPolys[j]);
+                }
+            }
+        }
+    }
+
+    for (i = 0; i < coeffs->nX; i++) {
+        for (j = 0; j < coeffs->nY; j++) {
+            coeffs->coeff[i][j] = sums[i][j];
+            coeffs->coeff[i][j] /= (float)(input->numRows * input->numCols);
+
+            if ((i != 0) && (j != 0)) {
+                coeffs->coeff[i][j] *= 4.0;
+            } else if ((i == 0) && (j == 0)) {
+                coeffs->coeff[i][j] *= 1.0;
+            } else {
+                coeffs->coeff[i][j] *= 2.0;
+            }
+        }
+    }
+
+    // Free the Chebyshev polynomials that were
+    // created in this routine.
+    for (i = 0; i < maxChebyPoly; i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+
+    // Free some data
+    for (i = 0; i < coeffs->nX; i++) {
+        psFree(sums[i]);
+    }
+    psFree(sums);
+    psFree(cScalingFactors);
+    psFree(rScalingFactors);
+
+    return (coeffs);
+}
+
+/*****************************************************************************
+XXX: Use static variables for chebyshev polynomials and scaling factors. 
+ 
+XXX: Currently we only support F32.
+ *****************************************************************************/
+psImage* psImageEvalPolynomial(psImage* input, const psPolynomial2D* coeffs)
+{
+    int x = 0;
+    int y = 0;
+    int i = 0;
+    int j = 0;
+    //    float **sums = NULL;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+    float *cScalingFactors = NULL;
+    float *rScalingFactors = NULL;
+    float polySum = 0.0;
+
+    // Create the sums[][] data structure.  This will hold the LHS of
+    // equation 29 in the ADD:
+    //         sums[k][l] = SUM { image(x,y) * Tk(x) * Tl(y) }
+    //
+    //    sums = (float **)psAlloc(coeffs->nX * sizeof(float *));
+    //    for (i = 0; i < coeffs->nX; i++) {
+    //        sums[i] = (float *)psAlloc(coeffs->nY * sizeof(float));
+    //    }
+    //    for (i = 0; i < coeffs->nX; i++) {
+    //        for (j = 0; j < coeffs->nY; j++) {
+    //            sums[i][j] = 0.0;
+    //        }
+    //    }
+
+
+    // Check for null inputs
+    if (input == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageEvalPolynomial",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        return NULL;
+    }
+
+    if (coeffs == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageEvalPolynomial",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_COEFF_NULL);
+        return NULL;
+    }
+
+    // We scale the pixel positions to values between -1.0 and 1.0
+    // Use static data structures here.
+    rScalingFactors = p_psCalcScaleFactorsEval(input->numRows);
+    cScalingFactors = p_psCalcScaleFactorsEval(input->numCols);
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = coeffs->nX;
+    if (coeffs->nY > coeffs->nX) {
+        maxChebyPoly = coeffs->nY;
+    }
+
+    chebPolys = p_psCreateChebyshevPolys(maxChebyPoly);
+
+    for (x = 0; x < input->numRows; x++) {
+        for (y = 0; y < input->numCols; y++) {
+            polySum = 0.0;
+            for (i = 0; i < coeffs->nX; i++) {
+                for (j = 0; j < coeffs->nY; j++) {
+                    polySum +=
+                        psPolynomial1DEval(rScalingFactors[x], chebPolys[i]) *
+                        psPolynomial1DEval(cScalingFactors[y], chebPolys[j]) *
+                        coeffs->coeff[i][j];
+
+                }
+            }
+            input->data.F32[x][y] = polySum;
+        }
+    }
+
+    // Free the Chebyshev polynomials that were
+    // created in this routine.
+    // XXX: Use dtatic data structures here.
+    for (i = 0; i < maxChebyPoly; i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+
+    psFree(cScalingFactors);
+    psFree(rScalingFactors);
+
+    return input;
+}
Index: /branches/rel3/psLib/src/imageops/psImageStats.h
===================================================================
--- /branches/rel3/psLib/src/imageops/psImageStats.h	(revision 2163)
+++ /branches/rel3/psLib/src/imageops/psImageStats.h	(revision 2163)
@@ -0,0 +1,89 @@
+/** @file psImageStats.h
+*  \brief Routines for calculating statistics on images.
+*  @ingroup ImageStats
+*
+*  This file will hold the prototypes for procedures which calculate
+*  statistic on images, histograms on images, and fit/evaluate Chebyshev
+*  polynomials to images.
+*
+*  @author George Gusciora, MHPCC
+*
+*  @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-05 01:03:11 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#if !defined(PS_IMAGE_STATS_H)
+#define PS_IMAGE_STATS_H
+
+#include "psType.h"
+#include "psVector.h"
+#include "psImage.h"
+#include "psStats.h"
+#include "psFunctions.h"
+
+/// @addtogroup ImageStats
+/// @{
+
+/** This routine must determine the various statistics for the image.
+ *
+ *  Determine statistics for image (or subimage). The statistics to be 
+ *  determined are specified by stats. The mask allows pixels to be excluded 
+ *  if their corresponding mask pixel value matches the value of maskVal. 
+ *  This function must be defined for the following types: psS8, psU16, psF32, 
+ *  psF64.
+ *
+ *  @return psStats*    the resulting statistics result(s)
+ */
+psStats* psImageStats(
+    psStats* stats,                    ///< defines statistics to be calculated
+    psImage* in,                       ///< image (or subimage) to calculate stats
+    psImage* mask,                     ///< mask data for image (NULL ok)
+    int maskVal                        ///< mask Mask for mask
+);
+
+/** Construct a histogram from an image (or subimage).
+ *
+ *  The histogram to generate is specified by psHistogram hist (see section 
+ *  4.3.2 in SDRS). This function must be defined for the following types: 
+ *  psS8, psU16, psF32, psF64.
+ *
+ *  @return psHistogram*     the resulting histogram
+ */
+psHistogram* psImageHistogram(
+    psHistogram* out,                  ///< input histogram description & target
+    psImage* in,                       ///< Image data to be histogramed.
+    psImage* mask,                     ///< mask data for image (NULL ok)
+    unsigned int maskVal               ///< mask Mask for mask
+);
+
+/** Fit a 2-D polynomial surface to an image.
+ *
+ *  The input structure coeffs contains the desired order and terms of 
+ *  interest. This function must be defined for the following types: psS8, 
+ *  psU16, psF32, psF64.
+ *
+ *  @return psPolynomial2D*     fitted polynomial result
+ *
+ */
+psPolynomial2D* psImageFitPolynomial(
+    psPolynomial2D* coeffs,            ///< coefficient structure carries in desired terms & target
+    const psImage* input
+);
+
+/** Evaluate a 2-D polynomial surface for the image pixels.
+ *
+ *  Given the input polynomial coefficients, set the image pixel values on the 
+ *  basis of the polynomial function. This function must be defined for the 
+ *  following types: psS8, psU16, psF32, psF64.
+ *
+ *  @return psImage*    the resulting image
+ */
+psImage* psImageEvalPolynomial(
+    psImage* input,                    ///< input image
+    const psPolynomial2D* coeffs       ///< coefficient structure carries in desired terms
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/mainpage.dox
===================================================================
--- /branches/rel3/psLib/src/mainpage.dox	(revision 2163)
+++ /branches/rel3/psLib/src/mainpage.dox	(revision 2163)
@@ -0,0 +1,153 @@
+/** @mainpage psLib Image Processing Library
+
+
+@section intro Introduction
+
+This library contains the Pan-STARRS Image Processing Pipeline (IPP) common library,
+psLib. The intended use is to provide a set of basic software functions in which
+can be used throughout the Pan-STARRS project to simplify programming tasks. Among
+the benefits are: 
+ - reuse of code, 
+ - simplification of testing, 
+ - streamlining of code, and 
+ - isolation of functionality that may be subject to change.     
+
+The capabilities provided by psLib are grouped into the following areas which are
+also reflected in the file system directory structure:
+ - System Utilities
+ - Data Collections
+ - Image Operations
+ - Data Manipulation
+ - Astronomy
+
+This list is sorted in hierarchical order: The later entries depend on the functions and 
+data types of the earlier entries.
+
+The installed code for psLib consists of header files and binary libraries in 
+the form of static (libpslib.a) and shared (libpslib.so or libpslib.dylib, 
+depending on operating system.) Assuming these components have been built and 
+installed in the standard library path, psLib may be used within a program by 
+including the line #include <pslib.h> and linking using the '-lpslib' option
+while linking.
+
+
+@section extinstall Required 3rd Party Libraries
+
+Before building psLib from source, several 3rd party software libraries must 
+be installed.  These include: 
+ - GNU Scientific Library (GSL)
+     - Available at http://www.gnu.org/software/gsl
+     - Compatibility tested with version is 1.4
+ - Fastest Fourier Transform in the West (FFTW), version 3
+     - Available at http://www.fftw.org
+     - Compatibility tested with version is 3.0.1
+ - C Flexible Image Transport System Input output (CFITSIO), version 2.480 or later
+     - Available at http://heasarc.gsfc.nasa.gov/docs/software/fitsio
+     - Compatibility tested with version is 2.490
+     - Versions earlier than 2.480 will not work as new functionality introduced in 2.480 is exercised
+ - Doxygen Documentation System
+     - Available at http://www.doxygen.org
+     - Compatibility tested with version 1.3.6
+     - The optional companion package, GraphViz (a.k.a., the 'dot' command), is recommended to enable header-file dependency diagrams
+ - SLALIB 
+     - We tested with the Fortran version of the library; this may cause an additional step to get things to link on untested systems/compilers, as there is no one standard for how the function-names appear in the library to C code.  The default way that psLib uses is all-lower case with a trailing '_', but one may need to add to CFLAGS in src/Makefile.Globals the following:
+         - '-DFORTRAN_UNDERSCORE_PREFIX' if a '_' needs to be prefixed to the function names,
+         - '-DFORTRAN_DOUBLE_UNDERSCORE_SUFFIX' if two the names needs two trailing '_'s., and/or
+         - '-DFORTRAN_UPPERCASE' if the names appear as uppercase.
+     - Available at http://star-www.rl.ac.uk/
+     - Compatibility tested with package version number 2.4-12
+
+We recommend using the particular versions listed as compatibility tested, as 
+that is the only versions of the external libraries tested to work well with psLib.  
+Though it is quite possible that later versions of the libraries listed will also 
+work as well, care must be taken when upgrading these libraries to verify that its
+functionality is compatible with the tested version.
+
+@section install How to Build from Source
+
+Tested versions of psLib are put into a tar file and can be downloaded from:
+
+https://mhpcc.pan-starrs.org/code/releases
+
+Though MHPCC recommends using the released packaged tar files descibed above,
+both daily development snapshots and direct CVS access is available.  The daily
+snapshots are available at
+
+https://mhpcc.pan-starrs.org/code/snapshots
+
+These snapshots represents development code as found in CVS on the day 
+specified in the filename.  This code set may not be functional, vary in
+testing, etc.  Reasonable efforts are made to ensure that the code does 
+actually compile, but given the nature of code development, even that is not 
+always the case.  Use snapshots with great caution.
+
+If one has a login account on mhpcc.pan-starrs.org, direct CVS access is  
+possible.  Example of the commands required for direct CVS retrieval are
+as follows:
+<pre>
+$ cvs -d:ext:USERNAME@mhpcc.pan-starrs.org:/data/panstarrs/cvsroot co -r RELEASEBRANCH psLib
+</pre>
+where:
+  - USERNAME is your login name on the server
+  - RELEASEBRANCH is the desired release branch, e.g. rel1, rel2, etc.
+    
+
+@section build How to Build the psLib library.
+
+The source should build using the Makefile in the psLib/src directory.  The
+recommended steps are:
+<pre>
+$ cd psLib/src
+$ make
+$ make install
+</pre>
+<i>This builds and installs files to psLib/lib and psLib/include.</i>
+
+
+@section run How to Build and Run Tests
+
+Since psLib is a library, there is no executable, per se. However, to test the 
+installation, users may execute the unit test suite.  To build the unit test
+suite, do the following:
+<pre>
+$ cd psLib/test
+$ make
+$ make install
+</pre>
+<i>This builds and installs the unit test files to the psLib/testbin directory.</i>
+
+To run the unit test suite, do the following:
+<pre>
+$ cd psLib/testbin
+$ ./FullUnitTest
+</pre>
+or to run a particular test
+<pre>
+$ ./runTest testfilename
+</pre>
+
+Note: one can also fun the FullUnitTest from anywhere within psLib/test
+without performing the above 'make installtests' command first.  To do this,
+one needs to first set the PSLIB_ROOT environment variable to the top psLib
+directory 'psLib'.  FullUnitTest will search for tests in the subdirectories
+the the execution directory, perform a build of them (via 'make'), and run them.
+This can be useful if one wants to tweak the test code and doesn't desire to
+perform an install of all the tests each time the test file is touched.
+
+
+@section doc How to Create Code Documentation
+
+Both HTML and man page documentation may be generated from the inline 
+documentation embedded in the code using the following commands:
+<pre>
+$ cd psLib/src
+$ make docs
+</pre>
+<i>This places documentation in psLib/docs.</i>
+
+Also, a prebuilt set of code documentation for both the releases and last 
+CVS snapshot can be found at:
+
+https://mhpcc.pan-starrs.org/docs/
+
+*/
Index: /branches/rel3/psLib/src/math/psCompare.c
===================================================================
--- /branches/rel3/psLib/src/math/psCompare.c	(revision 2163)
+++ /branches/rel3/psLib/src/math/psCompare.c	(revision 2163)
@@ -0,0 +1,80 @@
+
+/** @file psCompare.c
+ *  @brief Comparison functions for sorting routines
+ *  @ingroup Compare
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-07 00:06:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "psType.h"
+#include "psCompare.h"
+
+#define COMPARE_NUMERIC_PTR(TYPE) \
+int psCompare##TYPE##Ptr(const void** a, const void** b) { \
+    return **((ps##TYPE**)a) - **((ps##TYPE**)b); \
+}
+
+#define COMPARE_NUMERIC_PTR_DESCENDING(TYPE) \
+int psCompareDescending##TYPE##Ptr(const void** a, const void** b) { \
+    return **((ps##TYPE**)b) - **((ps##TYPE**)a); \
+}
+
+#define COMPARE_NUMERIC(TYPE) \
+int psCompare##TYPE(const void* a, const void* b) { \
+    return *((ps##TYPE*)a) - *((ps##TYPE*)b); \
+}
+
+#define COMPARE_NUMERIC_DESCENDING(TYPE) \
+int psCompare##TYPE##Descending(const void* a, const void* b) { \
+    return *((ps##TYPE*)b) - *((ps##TYPE*)a); \
+}
+
+COMPARE_NUMERIC_PTR(S8)
+COMPARE_NUMERIC_PTR(S16)
+COMPARE_NUMERIC_PTR(S32)
+COMPARE_NUMERIC_PTR(S64)
+COMPARE_NUMERIC_PTR(U8)
+COMPARE_NUMERIC_PTR(U16)
+COMPARE_NUMERIC_PTR(U32)
+COMPARE_NUMERIC_PTR(U64)
+COMPARE_NUMERIC_PTR(F32)
+COMPARE_NUMERIC_PTR(F64)
+
+COMPARE_NUMERIC_PTR_DESCENDING(S8)
+COMPARE_NUMERIC_PTR_DESCENDING(S16)
+COMPARE_NUMERIC_PTR_DESCENDING(S32)
+COMPARE_NUMERIC_PTR_DESCENDING(S64)
+COMPARE_NUMERIC_PTR_DESCENDING(U8)
+COMPARE_NUMERIC_PTR_DESCENDING(U16)
+COMPARE_NUMERIC_PTR_DESCENDING(U32)
+COMPARE_NUMERIC_PTR_DESCENDING(U64)
+COMPARE_NUMERIC_PTR_DESCENDING(F32)
+COMPARE_NUMERIC_PTR_DESCENDING(F64)
+
+COMPARE_NUMERIC(S8)
+COMPARE_NUMERIC(S16)
+COMPARE_NUMERIC(S32)
+COMPARE_NUMERIC(S64)
+COMPARE_NUMERIC(U8)
+COMPARE_NUMERIC(U16)
+COMPARE_NUMERIC(U32)
+COMPARE_NUMERIC(U64)
+COMPARE_NUMERIC(F32)
+COMPARE_NUMERIC(F64)
+
+COMPARE_NUMERIC_DESCENDING(S8)
+COMPARE_NUMERIC_DESCENDING(S16)
+COMPARE_NUMERIC_DESCENDING(S32)
+COMPARE_NUMERIC_DESCENDING(S64)
+COMPARE_NUMERIC_DESCENDING(U8)
+COMPARE_NUMERIC_DESCENDING(U16)
+COMPARE_NUMERIC_DESCENDING(U32)
+COMPARE_NUMERIC_DESCENDING(U64)
+COMPARE_NUMERIC_DESCENDING(F32)
+COMPARE_NUMERIC_DESCENDING(F64)
Index: /branches/rel3/psLib/src/math/psCompare.h
===================================================================
--- /branches/rel3/psLib/src/math/psCompare.h	(revision 2163)
+++ /branches/rel3/psLib/src/math/psCompare.h	(revision 2163)
@@ -0,0 +1,506 @@
+#if !defined(PS_COMPARE_H)
+#define PS_COMPARE_H
+
+/** @file psCompare.h
+ *  @brief Comparison functions for sorting routines
+ *
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @ingroup Compare
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-11 19:58:11 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/** @addtogroup Compare
+*  @{
+*/
+
+/** A comparison function for sorting elements that are pointers to data,
+ *  e.g., for psList of pointers to numeric values.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+typedef int (*psComparePtrFcn) (
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** A comparison function for sorting.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+typedef int (*psCompareFcn) (
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+/** Compare function of psS8 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareS8Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psS16 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareS16Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psS32 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareS32Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psS64 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareS64Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psU8 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareU8Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psU16 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareU16Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psU32 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareU32Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psU64 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareU64Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psF32 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareF32Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psF64 data.  For use with psListSort.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareF64Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psS8 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingS8Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psS16 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingS16Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psS32 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingS32Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psS64 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingS64Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psU8 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingU8Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psU16 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingU16Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psU32 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or lessg than the second. 
+ */
+int psCompareDescendingU32Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psU64 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or lessg than the second. 
+ */
+int psCompareDescendingU64Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psF32 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or lessg than the second. 
+ */
+int psCompareDescendingF32Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psF64 data.  For use with psListSort for descending ordering.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or lessg than the second. 
+ */
+int psCompareDescendingF64Ptr(
+    const void **a,                    ///< first comparison target
+    const void **b                     ///< second comparison target
+);
+
+/** Compare function of psS8 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareS8(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psS16 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareS16(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psS32 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareS32(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psS64 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareS64(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psU8 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareU8(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psU16 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareU16(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psU32 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareU32(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psU64 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareU64(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psF32 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareF32(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psF64 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively less 
+ *                   than, equal to, or greater than the second. 
+ */
+int psCompareF64(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psS8 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingS8(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psS16 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingS16(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psS32 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingS32(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psS64 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingS64(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psU8 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingU8(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psU16 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingU16(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psU32 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingU32(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psU64 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingU64(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psF32 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingF32(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/** Compare function of psF64 data.
+ *
+ *  @return int      an integer less than, equal to, or greater than zero if 
+ *                   the first argument is considered to be respectively greater 
+ *                   than, equal to, or less than the second. 
+ */
+int psCompareDescendingF64(
+    const void *a,                     ///< first comparison target
+    const void *b                      ///< second comparison target
+);
+
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/math/psConstants.h
===================================================================
--- /branches/rel3/psLib/src/math/psConstants.h	(revision 2163)
+++ /branches/rel3/psLib/src/math/psConstants.h	(revision 2163)
@@ -0,0 +1,205 @@
+/** @file  psComments.h
+ *
+ *  This file will hold definitions of various constants as well as common
+ *  macros used throughout psLib.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 23:43:12 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#define DETERMINE_BRACKET_STEP_SIZE 0.10
+#define MAX_LMM_ITERATIONS 100
+#define MAX_MINIMIZE_ITERATIONS 100
+#define LEFT_SPLINE_DERIV 0.0
+#define RIGHT_SPLINE_DERIV 0.0
+
+#define CONVERT_VECTOR_F64_TO_F32(OLD, NEW_PTR32, NEW_STATIC32) \
+if (OLD->type.type == PS_TYPE_F32) { \
+    NEW_PTR32 = (psVector *) OLD; \
+} else if (OLD->type.type == PS_TYPE_F64) { \
+    NEW_STATIC32 = psVectorRecycle(NEW_STATIC32, OLD->n, PS_TYPE_F32); \
+    p_psMemSetPersistent(NEW_STATIC32, true); \
+    p_psMemSetPersistent(NEW_STATIC32->data.V, true); \
+    for (i=0; i < OLD->n ; i++) { \
+        NEW_STATIC32->data.F32[i] = (float) OLD->data.F64[i]; \
+    } \
+    NEW_PTR32 = NEW_STATIC32; \
+} \
+
+#define CONVERT_VECTOR_F32_TO_F64(OLD, NEW_PTR64, NEW_STATIC64) \
+if (OLD->type.type == PS_TYPE_F64) { \
+    NEW_PTR64 = (psVector *) OLD; \
+} else if (OLD->type.type == PS_TYPE_F32) { \
+    NEW_STATIC64 = psVectorRecycle(NEW_STATIC64, OLD->n, PS_TYPE_F64); \
+    p_psMemSetPersistent(NEW_STATIC64, true); \
+    p_psMemSetPersistent(NEW_STATIC64->data.V, true); \
+    for (i=0; i < OLD->n ; i++) { \
+        NEW_STATIC64->data.F64[i] = (double) OLD->data.F32[i]; \
+    } \
+    NEW_PTR64 = NEW_STATIC64; \
+} \
+
+#define VECTOR_CHECK_TYPE_F32_OR_F64_RETURN_NULL(VEC) \
+if ((VEC->type.type != PS_TYPE_F32) && (VEC->type.type != PS_TYPE_F64)) { \
+    psAbort(__func__, "Bad type for VEC (%d)", VEC->type.type); \
+    return(NULL); \
+} \
+
+#define GEN_PERSIST_YERR_VEC_F32(VEC, N) \
+VEC = psVectorRecycle(VEC, N, PS_TYPE_F32); \
+p_psMemSetPersistent(VEC, true); \
+p_psMemSetPersistent(VEC->data.V, true); \
+for (int i=0;i<N;i++) { \
+    VEC->data.F32[i] = 1.0; \
+} \
+
+#define GEN_PERSIST_YERR_VEC_F64(VEC, N) \
+VEC = psVectorRecycle(VEC, N, PS_TYPE_F64); \
+p_psMemSetPersistent(VEC, true); \
+p_psMemSetPersistent(VEC->data.V, true); \
+for (int i=0;i<N;i++) { \
+    VEC->data.F64[i] = 1.0; \
+} \
+
+#define GEN_PERSIST_X_INDEX_VEC_F32(VEC, N) \
+VEC = psVectorRecycle(VEC, N, PS_TYPE_F32); \
+p_psMemSetPersistent(VEC, true); \
+p_psMemSetPersistent(VEC->data.V, true); \
+for (int i=0;i<N;i++) { \
+    VEC->data.F32[i] = (float) i; \
+} \
+
+#define GEN_PERSIST_X_INDEX_VEC_F64(VEC, N) \
+VEC = psVectorRecycle(VEC, N, PS_TYPE_F64); \
+p_psMemSetPersistent(VEC, true); \
+p_psMemSetPersistent(VEC->data.V, true); \
+for (int i=0;i<N;i++) { \
+    VEC->data.F64[i] = (float) i; \
+} \
+
+#define GEN_STATIC_RECYCLED_VECTOR(NAME, SIZE, TYPE) \
+static psVector *NAME = NULL; \
+NAME = psVectorRecycle(NAME, SIZE, TYPE); \
+p_psMemSetPersistent(NAME, true); \
+p_psMemSetPersistent(NAME->data.V, true); \
+
+
+
+
+
+
+/** Preprocessor macro to generate error on an incorrect type */
+#define PS_CHECK_VECTOR_TYPE_RETURN_NULL(NAME, TYPE) \
+if (NAME->type.type != TYPE) { \
+    psError(__func__,"Unallowable operation: %s has incorrect type.", #NAME); \
+    return(NULL); \
+}
+
+/** Preprocessor macro to generate error on a NULL vector */
+#define PS_CHECK_NULL_VECTOR_RETURN_NULL(NAME) \
+if (NAME == NULL || NAME->data.V == NULL) { \
+    psError(__func__,"Unallowable operation: %s or its data is NULL.", #NAME); \
+    return(NULL); \
+} \
+
+/** Preprocessor macro to generate error on a NULL poniter */
+#define PS_CHECK_NULL_PTR_RETURN_NULL(NAME) \
+if (NAME == NULL) { \
+    psError(__func__,"Unallowable operation: %s is NULL.", #NAME); \
+    return(NULL); \
+}
+/** Preprocessor macro to generate error on a NULL poniter */
+#define PS_CHECK_NULL_PTR_RETURN_ZERO(NAME) \
+if (NAME == NULL) { \
+    psError(__func__,"Unallowable operation: %s is NULL.", #NAME); \
+    return(0); \
+}
+
+/** Preprocessor macro to generate error for zero length vector */
+#define PS_CHECK_EMPTY_VECTOR_RETURN_NULL(NAME) \
+if (NAME->n < 1) { \
+    psError(__func__,"Unallowable operation: %s has zero n value.", #NAME); \
+    return(NULL); \
+} \
+
+/** Preprocessor macro to generate error on differing size vectors */
+#define PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(VEC1, VEC2) \
+if (VEC1->n != VEC2->n) { \
+    psError(__func__,"Vector %s has size %d, Vector %s has size %d.", #VEC1, VEC1->n, #VEC2, VEC2->n); \
+    return(NULL); \
+}
+
+/** Preprocessor macro to generate error on differing size vectors */
+#define PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(VEC1, VEC2) \
+if (VEC1->n != VEC2->n) { \
+    psError(__func__,"Vector %s has size %d, Vector %s has size %d.", #VEC1, VEC1->n, #VEC2, VEC2->n); \
+    return(NULL); \
+}
+
+/** Preprocessor macro to generate error on a NULL image */
+#define PS_CHECK_NULL_IMAGE_RETURN_NULL(NAME) \
+if (NAME == NULL || NAME->data.V == NULL) {                                                         \
+    psError(__func__,"Unallowable operation: %s or its data is NULL.", #NAME);                          \
+    return(NULL); \
+}
+
+/** Preprocessor macro to generate error for zero length rows or columns */
+#define PS_CHECK_EMPTY_IMAGE_RETURN_NULL(NAME) \
+if (NAME->numCols < 1 || NAME->numRows < 1) {                                                       \
+    psError(__func__,"Unallowable operation: %s has zero rows or columns (%dx%d).", #NAME,              \
+            NAME->numCols, NAME->numRows);                                                          \
+    return(NULL); \
+}
+
+#define PS_CHECK_IMAGE_TYPE_RETURN_NULL(NAME, TYPE) \
+if (NAME->type.type != TYPE) { \
+    psError(__func__,"Unallowable operation: %s has incorrect type.", #NAME); \
+    return(NULL); \
+}
+
+/** Preprocessor macro to generate error on a NULL image */
+#define PS_CHECK_NULL_IMAGE_READOUT_NULL(NAME) \
+if (NAME == NULL || NAME->image == NULL) {                                                         \
+    psError(__func__,"Unallowable operation: %s or its data is NULL.", #NAME);                          \
+    return(NULL); \
+}
+
+#define PS_CHECK_NULL_1DPOLY_RETURN_NULL(NAME)                                                          \
+if (NAME == NULL || NAME->coeff == NULL) {                                                         \
+    psError(__func__,"Unallowable operation: %s or its coeffs is NULL.", #NAME);                          \
+    return(NULL); \
+} \
+
+
+
+
+
+#define PS_PRINT_VECTOR(NAME) \
+for (int my_i=0;my_i<NAME->n;my_i++) { \
+    printf("%s->data.F32[%d] is %f\n", #NAME, my_i, NAME->data.F32[my_i]); \
+} \
+printf("\n"); \
+
+#define PS_VECTOR_F64_TO_F32(X64, X32) \
+psVector *X32 = psVectorAlloc(X64->n, PS_TYPE_F32); \
+for (int i=0;i<X64->n;i++) { \
+    X32->data.F32[i] = (float) X64->data.F64[i]; \
+} \
+
+#define PS_VECTOR_F32_TO_F64(X32, X64) \
+psVector *X64 = psVectorAlloc(X32->n, PS_TYPE_F64); \
+for (int i=0;i<X32->n;i++) { \
+    X64->data.F64[i] = (float) X32->data.F32[i]; \
+} \
+
+
+#define PS_MAX(A, B) \
+((A > B) ? A : B) \
+
+#define PS_MIN(A, B) \
+((A < B) ? A : B) \
+
Index: /branches/rel3/psLib/src/math/psMatrix.c
===================================================================
--- /branches/rel3/psLib/src/math/psMatrix.c	(revision 2163)
+++ /branches/rel3/psLib/src/math/psMatrix.c	(revision 2163)
@@ -0,0 +1,539 @@
+/** @file  psMatrix.c
+ *
+ *  @brief Provides functions for linear algebra operations on psImages and psVectors. 
+ *
+ *  Functions are provided to:
+ *      Transpose a psImage
+ *      Compute LUD
+ *      Solve LUD
+ *      Matrix inversion
+ *      Calculate determinant
+ *      Matrix addition
+ *      Matrix subtraction
+ *      Matrix multiplication
+ *      Calculate Eigenvectors
+ *      Convert matrix to vector
+ *      Convert vector to matrix
+ *
+ *  These functions treat psImages as if they were matrices, therefore there is no psMatrix.
+ *
+ *  @author Ross Harman, MHPCC
+ *   
+ *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-08 02:48:01 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include <string.h>
+#include <gsl/gsl_matrix.h>
+#include <gsl/gsl_linalg.h>
+#include <gsl/gsl_permutation.h>
+#include <gsl/gsl_eigen.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psImage.h"
+#include "psVector.h"
+#include "psMatrix.h"
+
+/** Preprocessor macro to generate error a NULL image */
+#define PS_CHECK_NULL_VECTOR(NAME, RETURN)                                                          \
+if (NAME == NULL || NAME->data.V == NULL) {                                                         \
+    psError(__func__,"Invalid operation: %s or its data is NULL.", #NAME);                          \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to create vector based on another */
+#define PS_CHECK_ALLOC_VECTOR(NAME, SIZE, PS_TYPE)                                                  \
+if(NAME == NULL) {                                                                                  \
+    NAME = psVectorAlloc(SIZE, PS_TYPE);                                                            \
+}
+
+/** Preprocessor macro to generate error for zero length vector */
+#define PS_CHECK_SIZE_VECTOR(NAME, RETURN)                                                          \
+if (NAME->n < 1) {                                                                                  \
+    psError(__func__,"Invalid operation: %s has zero n value.", #NAME);                             \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to generate error a NULL image */
+#define PS_CHECK_NULL_IMAGE(NAME, RETURN)                                                           \
+if (NAME == NULL || NAME->data.V == NULL) {                                                         \
+    psError(__func__,"Invalid operation: %s or its data is NULL.", #NAME);                          \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to create image based on another */
+#define PS_CHECK_ALLOC_IMAGE(NAME, NCOLS, NROWS, PS_TYPE)                                           \
+if(NAME == NULL) {                                                                                  \
+    NAME = psImageAlloc(NCOLS, NROWS, PS_TYPE);                                                     \
+}
+
+/** Preprocessor macro to generate error for zero length rows or columns */
+#define PS_CHECK_SIZE_IMAGE(NAME, RETURN)                                                           \
+if (NAME->numCols < 1 || NAME->numRows < 1) {                                                       \
+    psError(__func__,"Invalid operation: %s has zero rows or columns (%dx%d).", #NAME,              \
+            NAME->numCols, NAME->numRows);                                                          \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to generate error for image dimensionality not set to PS_DIMEN_IMAGE */
+#define PS_CHECK_DIMEN_AND_TYPE(NAME, PS_DIMEN, RETURN)                                             \
+if (NAME->type.dimen != PS_DIMEN) {                                                                 \
+    psError(__func__,"Invalid operation: %s incorrect dimensionality %d.", #NAME, PS_DIMEN);        \
+    return RETURN;                                                                                  \
+} else if(NAME->type.type != PS_TYPE_F64) {                                                         \
+    psError(__func__, "Invalid operation: %s not PS_TYPE_F64.", #NAME);                             \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to check that input is not equal to output */
+#define PS_CHECK_POINTERS(NAME1, NAME2, RETURN)                                                     \
+if (NAME1 == NAME2) {                                                                               \
+    psError(__func__,"Invalid operation: Pointer to %s is same as %s.", #NAME1, #NAME2);            \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to check that an image is square */
+#define PS_CHECK_SQUARE(NAME, RETURN)                                                               \
+if (NAME->numCols != NAME->numRows) {                                                               \
+    psError(__func__,"Invalid operation: %s not square array.", #NAME);                             \
+    return RETURN;                                                                                  \
+}
+
+/** Preprocessor macro to initalize a GSL matrix. */
+#define PS_GSL_MATRIX_INITIALIZE(LHS_NAME, RHS_NAME)                                                \
+LHS_NAME.size1 = numRows;                                                                           \
+LHS_NAME.size2 = numCols;                                                                           \
+LHS_NAME.tda   = numCols;                                                                           \
+LHS_NAME.data  = RHS_NAME;
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+psImage* psMatrixLUD(psImage* outImage, psVector* outPerm, psImage* inImage)
+{
+    int signum = 0;
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix lu;
+    gsl_permutation perm;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_NULL_IMAGE(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+    PS_CHECK_ALLOC_VECTOR(outPerm, inImage->numRows, inImage->type.type);
+    PS_CHECK_NULL_VECTOR(outPerm, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(outPerm, PS_DIMEN_VECTOR, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type) * numRows * numCols;
+
+    // Initialize GSL data
+    perm.size = numCols;
+    outPerm->n = numCols;
+    perm.data = outPerm->data.V;
+    PS_GSL_MATRIX_INITIALIZE(lu, outImage->data.V[0]);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Copy psImage input data into GSL matrix data to keep input data pristine
+    memcpy(lu.data, inImage->data.V[0], arraySize);
+
+    // Calculate LU decomposition
+    gsl_linalg_LU_decomp(&lu, &perm, &signum);
+
+    return outImage;
+}
+
+psVector* psMatrixLUSolve(psVector* outVector, const psImage* inImage,
+                          const psVector* inVector, const psVector* inPerm)
+{
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix lu;
+    gsl_permutation perm;
+    gsl_vector b;
+    gsl_vector x;
+
+    // Error checks
+    PS_CHECK_POINTERS(outVector, inVector, outVector);
+    PS_CHECK_POINTERS(inVector, inPerm, outVector);
+    PS_CHECK_POINTERS(outVector, inPerm, outVector);
+    PS_CHECK_NULL_IMAGE(inImage, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outVector);
+    PS_CHECK_SIZE_IMAGE(inImage, outVector);
+    PS_CHECK_ALLOC_VECTOR(outVector, inImage->numRows, inImage->type.type);
+    PS_CHECK_NULL_VECTOR(outVector, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_VECTOR, outVector);
+    PS_CHECK_NULL_VECTOR(inVector, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_VECTOR, outVector);
+    PS_CHECK_NULL_VECTOR(inPerm, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inPerm, PS_DIMEN_VECTOR, outVector);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type) * numRows * numCols;
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(lu, inImage->data.V[0]);
+
+    outVector->n = numCols;
+
+    perm.size = inPerm->n;
+    perm.data = inPerm->data.V;
+
+    b.size = inVector->n;
+    b.stride = 1;
+    b.data = inVector->data.V;
+
+    x.size = numCols;
+    x.stride = 1;
+    x.data = outVector->data.V;
+
+    // Solve for {x} in equation: {b} = [A]{x}
+    gsl_linalg_LU_solve(&lu, &perm, &b, &x);
+
+    return outVector;
+}
+
+psImage* psMatrixInvert(psImage* outImage, const psImage* inImage, float *restrict det)
+{
+    int signum = 0;
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix inv;
+    gsl_matrix *lu;
+    gsl_permutation *perm = NULL;
+
+    // Error checks
+    if (det == NULL) {
+        psError(__func__, "Invalid operation: determinant argument is NULL.");
+        return outImage;
+    }
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_NULL_IMAGE(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type) * numRows * numCols;
+
+    // Allocate GSL structs
+    perm = gsl_permutation_alloc(inImage->numRows);
+    lu = gsl_matrix_alloc(numRows, numCols);
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(inv, outImage->data.V[0]);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Copy psImage input data into GSL matrix data to keep input data pristine
+    memcpy(lu->data, inImage->data.V[0], arraySize);
+
+    // Invert data and calculate determinant
+    gsl_linalg_LU_decomp(lu, perm, &signum);
+    gsl_linalg_LU_invert(lu, perm, &inv);
+    *det = (float)gsl_linalg_LU_det(lu, signum);
+
+    // Free GSL structs
+    gsl_permutation_free(perm);
+    gsl_matrix_free(lu);
+
+    return outImage;
+}
+
+float *psMatrixDeterminant(const psImage* restrict inImage)
+{
+    int signum = 0;
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    float *det = NULL;
+    gsl_matrix *lu = NULL;
+    gsl_permutation *perm = NULL;
+
+    // Error checks
+    PS_CHECK_NULL_IMAGE(inImage, NULL);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, NULL);
+    PS_CHECK_SIZE_IMAGE(inImage, NULL);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type) * numRows * numCols;
+
+    // Allocate GSL structs
+    perm = gsl_permutation_alloc(numRows);
+    lu = gsl_matrix_alloc(numRows, numCols);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, 0);
+
+    // Copy psImage input data into GSL matrix data to keep input data pristine
+    memcpy(lu->data, inImage->data.V[0], arraySize);
+
+    // Calculate determinant
+    det = (float *)psAlloc(sizeof(float));
+    gsl_linalg_LU_decomp(lu, perm, &signum);
+    *det = (float)gsl_linalg_LU_det(lu, signum);
+
+    // Free GSL structs
+    gsl_permutation_free(perm);
+    gsl_matrix_free(lu);
+
+    return det;
+}
+
+psImage* psMatrixMultiply(psImage* outImage, psImage* inImage1, psImage* inImage2)
+{
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix m1;
+    gsl_matrix m2;
+    gsl_matrix m3;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage1, outImage, outImage);
+    PS_CHECK_POINTERS(inImage1, inImage2, outImage);
+    PS_CHECK_NULL_IMAGE(inImage1, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage1, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage1, outImage);
+    PS_CHECK_NULL_IMAGE(inImage2, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage2, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage2, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage2->numCols, inImage2->numRows, inImage2->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(inImage1, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage1->numRows;
+    numCols = inImage1->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(outImage->type.type) * numRows * numCols;
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(m1, inImage1->data.V[0]);
+    PS_GSL_MATRIX_INITIALIZE(m2, inImage2->data.V[0]);
+    PS_GSL_MATRIX_INITIALIZE(m3, outImage->data.V[0]);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage1, outImage);
+    PS_CHECK_SQUARE(inImage2, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    gsl_linalg_matmult(&m1, &m2, &m3);
+
+    return outImage;
+}
+
+psImage* psMatrixTranspose(psImage* outImage, const psImage* inImage)
+{
+    int arraySize = 0;
+    int numRows = 0;
+    int numCols = 0;
+    gsl_matrix trans;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_NULL_IMAGE(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+    arraySize = PSELEMTYPE_SIZEOF(inImage->type.type) * numRows * numCols;
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(trans, outImage->data.V[0]);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Copy psImage input data into psImage output data to keep input data pristine
+    memcpy(outImage->data.V[0], inImage->data.V[0], arraySize);
+
+    // Transpose data
+    gsl_matrix_transpose(&trans);
+
+    return outImage;
+}
+
+psImage* psMatrixEigenvectors(psImage* outImage, psImage* inImage)
+{
+    int numRows = 0;
+    int numCols = 0;
+    gsl_vector *eVals = NULL;
+    gsl_eigen_symmv_workspace *w = NULL;
+    gsl_matrix out;
+    gsl_matrix in;
+
+    // Error checks
+    PS_CHECK_POINTERS(inImage, outImage, outImage);
+    PS_CHECK_NULL_IMAGE(inImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(inImage, outImage);
+    PS_CHECK_ALLOC_IMAGE(outImage, inImage->numCols, inImage->numRows, inImage->type.type);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+    PS_CHECK_SIZE_IMAGE(outImage, outImage);
+
+    // Initialize data
+    numRows = inImage->numRows;
+    numCols = inImage->numCols;
+
+    // Initialize GSL data
+    PS_GSL_MATRIX_INITIALIZE(in, inImage->data.V[0]);
+    PS_GSL_MATRIX_INITIALIZE(out, outImage->data.V[0]);
+
+    // Allocate GSL structs
+    eVals = gsl_vector_alloc(numRows);
+    w = gsl_eigen_symmv_alloc(numRows);
+
+    // Non-square matrices not allowed
+    PS_CHECK_SQUARE(inImage, outImage);
+    PS_CHECK_SQUARE(outImage, outImage);
+
+    // Calculate Eigenvalues and Eigenvectors...Eigenvalues not currently used
+    gsl_eigen_symmv(&in, eVals, &out, w);
+
+    // Free GSL structs
+    gsl_eigen_symmv_free(w);
+    gsl_vector_free(eVals);
+
+    return outImage;
+}
+
+psVector* psMatrixToVector(psVector* outVector, const psImage* inImage)
+{
+    int size = 0;
+
+    // Error checks
+    PS_CHECK_NULL_IMAGE(inImage, outVector);
+    PS_CHECK_DIMEN_AND_TYPE(inImage, PS_DIMEN_IMAGE, outVector);
+    PS_CHECK_SIZE_IMAGE(inImage, outVector);
+
+    if (inImage->numRows == 1) {
+        // Create transposed row vector
+        PS_CHECK_ALLOC_VECTOR(outVector, inImage->numCols, inImage->type.type);
+        outVector->type.dimen = PS_DIMEN_TRANSV;
+    } else if (inImage->numCols == 1) {
+        // Create non-transposed column vector
+        PS_CHECK_ALLOC_VECTOR(outVector, inImage->numRows, inImage->type.type);
+    } else {
+        psError(__func__, "Image does not have dim with 1 col or 1 row: (%d x %d).", inImage->numRows,
+                inImage->numCols);
+        return outVector;
+    }
+
+    PS_CHECK_NULL_VECTOR(outVector, outVector);
+
+    // More checks
+    if (outVector->type.dimen == PS_DIMEN_VECTOR) {
+        PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_VECTOR, outVector);
+
+        if (outVector->n == 0) {
+            outVector->n = inImage->numRows;
+        }
+
+        if (outVector->n != inImage->numRows) {
+            psError(__func__, "Image and vector sizes differ: (%d vs %d).", inImage->numRows, outVector->n);
+            return outVector;
+        }
+
+        size = PSELEMTYPE_SIZEOF(inImage->type.type) * inImage->numRows;
+
+    } else if (outVector->type.dimen == PS_DIMEN_TRANSV) {
+        PS_CHECK_DIMEN_AND_TYPE(outVector, PS_DIMEN_TRANSV, outVector);
+
+        if (outVector->n == 0) {
+            outVector->n = inImage->numCols;
+        }
+
+        if (outVector->n != inImage->numCols) {
+            psError(__func__, "Image and vector sizes differ: (%d vs %d).", inImage->numCols, outVector->n);
+            return outVector;
+        }
+
+        size = PSELEMTYPE_SIZEOF(inImage->type.type) * inImage->numCols;
+    }
+
+    memcpy(outVector->data.V, inImage->data.V[0], size);
+
+    return outVector;
+}
+
+psImage* psVectorToMatrix(psImage* outImage, const psVector* inVector)
+{
+    int size = 0;
+
+    // Error checks
+    PS_CHECK_NULL_VECTOR(inVector, outImage);
+
+    if (inVector->type.dimen == PS_DIMEN_VECTOR) {
+        PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_VECTOR, outImage);
+        PS_CHECK_SIZE_VECTOR(inVector, outImage);
+        PS_CHECK_ALLOC_IMAGE(outImage, 1, inVector->n, PS_TYPE_F64)
+        // More checks for PS_DIMEN_VECTOR
+        if (outImage->numCols > 1) {
+            psError(__func__, "Image has more than 1 column: numCols = %d.", outImage->numCols);
+            return outImage;
+        } else if (outImage->numRows != inVector->n) {
+            psError(__func__, "Image and vector sizes differ: (%d vs %d).", outImage->numRows, inVector->n);
+            return outImage;
+        }
+
+        size = PSELEMTYPE_SIZEOF(outImage->type.type) * outImage->numRows;
+
+    } else if (inVector->type.dimen == PS_DIMEN_TRANSV) {
+        PS_CHECK_DIMEN_AND_TYPE(inVector, PS_DIMEN_TRANSV, outImage);
+        PS_CHECK_SIZE_VECTOR(inVector, outImage);
+        PS_CHECK_ALLOC_IMAGE(outImage, inVector->n, 1, PS_TYPE_F64)
+        // More checks for PS_DIMEN_TRANSV
+        if (outImage->numRows > 1) {
+            psError(__func__, "Image has more than 1 row: numRows = %d.", outImage->numRows);
+            return outImage;
+        } else if (outImage->numCols != inVector->n) {
+            psError(__func__, "Image and vector sizes differ: (%d vs %d).", outImage->numCols, inVector->n);
+            return outImage;
+        }
+
+        size = PSELEMTYPE_SIZEOF(outImage->type.type) * outImage->numCols;
+    }
+
+    PS_CHECK_NULL_IMAGE(outImage, outImage);
+    PS_CHECK_DIMEN_AND_TYPE(outImage, PS_DIMEN_IMAGE, outImage);
+
+    memcpy(outImage->data.V[0], inVector->data.V, size);
+
+    return outImage;
+}
Index: /branches/rel3/psLib/src/math/psMatrix.h
===================================================================
--- /branches/rel3/psLib/src/math/psMatrix.h	(revision 2163)
+++ /branches/rel3/psLib/src/math/psMatrix.h	(revision 2163)
@@ -0,0 +1,166 @@
+
+/** @file  psMatrix.h
+ *
+ *  @brief Provides functions for linear algebra operations on psImages and psVectors. 
+ *
+ *  Functions are provided to:
+ *      Transpose a psImage
+ *      Compute LUD
+ *      Solve LUD
+ *      Matrix inversion
+ *      Calculate determinant
+ *      Matrix multiplication
+ *      Calculate Eigenvectors
+ *      Convert matrix to vector
+ *      Convert vector to matrix
+ *
+ *  These functions treat psImages as if they were matrices, therefore there is no psMatrix. These functions
+ *  operate only with the psF64 data type.
+ *
+ *  @ingroup Matrix
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-21 23:44:10 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PSMATRIX_H
+#define PSMATRIX_H
+
+/// @addtogroup Matrix
+/// @{
+
+/** LU Decomposition of psImage matrix.
+ *
+ *  Performs a LU decomposition on a psImage matrix and returns the LU matrix. If the user specifies NULL for
+ *  the outImage or outPerm arguments, then they will be automatically created. The input image must 
+ *  be square. This function operates only with the psF64 data type. Input and output arguments should not be 
+ *  the same. GSL indexes the top row as the zero row, not the bottom.  
+ *
+ *  @return  psImage* : Pointer to LU decomposed psImage.
+ */
+psImage* psMatrixLUD(
+    psImage* outImage,                 ///< Image to return, or NULL.
+    psVector* outPerm,                 ///< Output permutation vector used by psMatrixLUSolve.
+    psImage* inImage                   ///< Image to decompose.
+);
+
+/** LU Solution of psImage matrix.
+ *
+ *  Solves for and returns the psVector, {x} in the equation [A]{x} = {b}. If the user specifies NULL as the 
+ *  outVector argument, then it will automatically be created. The input image must be square. This function 
+ *  operates only with the psF64 data type. Input and output arguments should not be the same. GSL indexes 
+ *  the top row as the zero row, not the bottom.  
+ *
+ *  @return  psVector* : Pointer to psVector solution of matrix equation.
+ */
+psVector* psMatrixLUSolve(
+    psVector* outVector,               ///< Vector to return, or NULL.
+    const psImage* luImage,            ///< LU-decomposed matrix.
+    const psVector* inVector,          ///< Vector right-hand-side of equation.
+    const psVector* inPerm             ///< Permutation vector resulting from psMatrixLUD function.
+);
+
+/** Invert psImage matrix.
+ *
+ *  Inverts a psImage matrix and returns the determinant as an option through the argument list. If the user
+ *  specifies NULL as the outImage argument, then it will automatically be created. The input image must be 
+ *  square. This function operates only with the psF64 data type. Input and output arguments should not be 
+ *  the same. GSL indexes the top row as the zero row, not the bottom.  
+ *
+ *  @return  psImage* : Pointer to inverted psImage.
+ */
+psImage* psMatrixInvert(
+    psImage* outImage,                 ///< Image to return, or NULL for in-place substitution.
+    const psImage* inImage,            ///< Image to be inverted
+    float *restrict det                ///< Determinant to return, or NULL
+);
+
+/** Calculate psImage matrix determinant.
+ *
+ *  Calculates the determinant of a psImage matrix and returns the single precision floating point result. The
+ *  input image must be square. This function operates only with the psF64 data type. GSL indexes the top row 
+ *  as the zero row, not the bottom.  
+ *
+ *  @return  float: Determinant from psImage.
+ */
+float *psMatrixDeterminant(
+    const psImage* restrict inMatrix   ///< Image used to calculate determinant.
+);
+
+/** Performs psImage matrix multiplication.
+ *
+ *  Performs a classical matrix multiplication involving row and column operations. Input images must be square 
+ *  and the same size. If the user specifies NULL as the outImage argument, then it will automatically be 
+ *  created. This function operates only with the psF64 data type. GSL indexes the top row as the
+ *  zero row, not the bottom.  
+ *
+ *  @return  psImage* : Pointer to resulting psImage.
+ */
+psImage* psMatrixMultiply(
+    psImage* outImage,                 ///< Matrix to return, or NULL.
+    psImage* inImage1,                 ///< First input image.
+    psImage* inImage2                  ///< Second input image.
+);
+
+/** Transpose matrix.
+ *
+ *  Performs psImage matrix transpose by substituting existing rows for columns. The input image must be 
+ *  square. If the user specifies NULL as the outImage argument, then it will automaticallty be created.
+ *  This function operates only with the psF64 data type. GSL indexes the top row as the zero 
+ *  row, not the bottom.  
+ *
+ *  @return  psImage* : Pointer to transposed psImage.
+ */
+psImage* psMatrixTranspose(
+    psImage* outImage,                 ///< Image to return, or NULL
+    const psImage* inImage             ///< Image to transpose
+);
+
+/** Calculate matrix eigenvectors.
+ *
+ *  Calculates the eigenvectors for a matrix. The input image must be symmetric and square. If the user 
+ *  specifies NULL as the outImage argument, then it will automatically be created. This function operates 
+ *  only with the psF64 data type. GSL indexes the top row as the zero row, not the bottom.  
+ *
+ *  @return  psImage* : Pointer to matrix of Eigenvectors.
+ */
+psImage* psMatrixEigenvectors(
+    psImage* outImage,                 ///< Eigenvectors to return, or NULL.
+    psImage* inImage                   ///< Input image.
+);
+
+/** Convert matrix to vector.
+ *
+ *  Converts a 1-d psImage matrix into a vector. If the user specifies NULL as the outVector argument, then it
+ *  will automatically be created based on the input image (PS_DIMEN_VECTOR for an input image with 1 col or
+ *  PS_DIMENT_TRANSV for an input image with 1 row). Either the number of rows or the number of colums of the
+ *  input matrix must be 1. This function operates only  with the psF64 data type.
+ *
+ *  @return  psVector* : Pointer to psVector.
+ */
+psVector* psMatrixToVector(
+    psVector* outVector,               ///< Vector to return, or NULL.
+    const psImage* inImage             ///< Image to convert.
+);
+
+/** Convert vector to matrix.
+ *
+ *  Converts a vector into a psImage matrix. If the dimensionality of the vector is PS_DIMEN_VECTOR, then the
+ *  resulting psImage is a 1d column. If the dimensionality of the vector is PS_DIMEN_TRANSV, then the
+ *  resulting psImage is a 1d row. If the user specifies NULL as the outImage argument,  then it will 
+ *  automatically be created. This function operates only with the psF64 data type.  
+ *
+ *  @return  psVector* : Pointer to psIamge.
+ */
+psImage* psVectorToMatrix(
+    psImage* outImage,                 ///< Matrix to return, or NULL.
+    const psVector* inVector           ///< Vector to convert.
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/math/psMinimize.c
===================================================================
--- /branches/rel3/psLib/src/math/psMinimize.c	(revision 2163)
+++ /branches/rel3/psLib/src/math/psMinimize.c	(revision 2163)
@@ -0,0 +1,1567 @@
+/** @file  psMinimize.c
+ *  \brief basic minimization functions
+ *  @ingroup Math
+ *
+ *  This file will contain functions to minimize an arbitrary function at
+ *  a data point, fit an arbitrary function to a set of data points, and
+ *  fit a 1-D polynomial to a set of data points.
+ *
+ *  @author GLF, MHPCC
+ *
+ *  @version $Revision: 1.58 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 01:44:48 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  XXX: must follow coding name standards on local functions.
+ *
+ *  XXX: Section 4.5.1.1 (predefined functions for Gauss minimization via
+ *       LMM) is not addressed here.  We are waiting for subsequent SDRs
+ *       which will redefine the LMM functions.
+ *
+ */
+/*****************************************************************************/
+/* INCLUDE FILES                                                             */
+/*****************************************************************************/
+#include "psMinimize.h"
+/*****************************************************************************/
+/* DEFINE STATEMENTS                                                         */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* TYPE DEFINITIONS                                                          */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* GLOBAL VARIABLES                                                          */
+/*****************************************************************************/
+static psMinimizeChi2PowellFunc Chi2PowellFunc = NULL;
+static psVector *myValue;
+static psVector *myError;
+
+/*****************************************************************************/
+/* FILE STATIC VARIABLES                                                     */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - LOCAL                                           */
+/*****************************************************************************/
+
+/******************************************************************************
+p_psBuildSums1D(x, polyOrder, sums): this routine calculates the powers of
+input parameter "x" between 0 and input parameter polyOrder.  The result is
+returned as a psVector sums.
+ 
+XXX: change name
+XXX: Use a static vector.
+ *****************************************************************************/
+void p_psBuildSums1D(double x,
+                     int polyOrder,
+                     psVector* sums)
+{
+    int i = 0;
+    double xSum = 0.0;
+
+    if (sums == NULL) {
+        sums = psVectorAlloc(polyOrder, PS_TYPE_F64);
+    }
+
+    if (polyOrder > sums->n) {
+        sums = psVectorRealloc(sums, polyOrder);
+    }
+
+    xSum = 1.0;
+    for (i = 0; i <= polyOrder; i++) {
+        sums->data.F64[i] = xSum;
+        xSum *= x;
+    }
+}
+
+/*****************************************************************************
+CalculateSecondDerivs(): Given a set of x/y vectors corresponding to a
+tabulated function at n points, this routine calculates the second
+derivatives of the interpolating cubic splines at those n points.
+ 
+The first and second derivatives at the endpoints, undefined in the SDR, are
+here defined to be 0.0.  They can be modified via ypo and yp1.
+ 
+This routine assumes that vectors x and y are of the appropriate types/sizes
+(F32).
+ 
+XXX: This algorithm is derived from the Numerical Recipes.
+XXX: use recycled vectors for internal data.
+XXX: do an F64 version?
+ *****************************************************************************/
+float *CalculateSecondDerivs(const psVector* restrict x,        ///< Ordinates (or NULL to just use the indices)
+                             const psVector* restrict y)        ///< Coordinates
+{
+    psTrace(".psLib.dataManip.CalculateSecondDerivs", 4,
+            "---- CalculateSecondDerivs() begin ----\n");
+
+    int i;
+    int k;
+    bool mustFreeX = false;
+    float sig;
+    float p;
+    int n = y->n;
+    float *u = (float *) psAlloc(n * sizeof(float));
+    float *derivs2 = (float *) psAlloc(n * sizeof(float));
+    float *X = (float *) & (x->data.F32[0]);
+    float *Y = (float *) & (y->data.F32[0]);
+    float qn;
+
+    // XXX: The second derivatives at the endpoints, undefined in the SDR,
+    // are set in psConstants.h: LEFT_SPLINE_DERIV, RIGHT_SPLINE_DERIV.
+    derivs2[0] = -0.5;
+    u[0]= (3.0/(X[1]-X[0])) * ((Y[1]-Y[0])/(X[1]-X[0]) - LEFT_SPLINE_DERIV);
+
+    for (i=1;i<=(n-2);i++) {
+        sig = (X[i] - X[i-1]) / (X[i+1] - X[i-1]);
+        p = sig * derivs2[i-1] + 2.0;
+        derivs2[i] = (sig - 1.0) / p;
+        u[i] = ((Y[i+1] - Y[i])/(X[i+1]-X[i])) - ((Y[i]-Y[i-1])/(X[i]-X[i-1]));
+        u[i] = ((6.0 * u[i] / (X[i+1] - X[i-1])) - (sig * u[i-1])) / p;
+
+        psTrace(".psLib.dataManip.CalculateSecondDerivs", 6,
+                "X[%d] is %f\n", i, X[i]);
+        psTrace(".psLib.dataManip.CalculateSecondDerivs", 6,
+                "Y[%d] is %f\n", i, Y[i]);
+        psTrace(".psLib.dataManip.CalculateSecondDerivs", 6,
+                "u[%d] is %f\n", i, u[i]);
+    }
+
+    qn = 0.5;
+    u[n-1] = (3.0/(X[n-1]-X[n-2])) * (RIGHT_SPLINE_DERIV - (Y[n-1]-Y[n-2])/(X[n-1]-X[n-2]));
+    derivs2[n-1] = (u[n-1] - (qn * u[n-2])) / ((qn * derivs2[n-2]) + 1.0);
+
+    for (k=(n-2);k>=0;k--) {
+        derivs2[k] = derivs2[k] * derivs2[k+1] + u[k];
+
+        psTrace(".psLib.dataManip.CalculateSecondDerivs", 6,
+                "derivs2[%d] is %f\n", k, derivs2[k]);
+    }
+
+    if (mustFreeX == true) {
+        psFree(X);
+    }
+    psFree(u);
+
+    psTrace(".psLib.dataManip.CalculateSecondDerivs", 4,
+            "---- CalculateSecondDerivs() end ----\n");
+    return(derivs2);
+}
+
+/******************************************************************************
+p_psNRSpline1DEval(): This routine does NR-style evaluation of cubic splines.
+It takes advantage of the 2nd derivatives of the cubic splines, which are
+stored in the psSPline1D data structure, and computes the interpolated value
+directly, without computing (or using) the interpolating cubic spline
+polynomial.
+ 
+This routine is here mostly for a sanity check on the psLib function
+evalSpline() which computes the interpolated value based on the cubic spline
+polynomials which are stored in psSpline1D.
+ 
+XXX: check types/sizes
+XXX: This is F32 only
+ *****************************************************************************/
+float p_psNRSpline1DEval(psSpline1D *spline,
+                         const psVector* restrict x,
+                         const psVector* restrict y,
+                         float X)
+{
+    int n;
+    int klo;
+    int khi;
+    float H;
+    float A;
+    float B;
+    float C;
+    float D;
+    float Y;
+
+    n = spline->n;
+    klo = p_psVectorBinDisectF32(spline->domains, (spline->n)+1, X);
+    khi = klo + 1;
+    H = (spline->domains)[khi] - (spline->domains)[klo];
+    A = ((spline->domains)[khi] - X) / H;
+    B = (X - (spline->domains)[klo]) / H;
+    C = ((A*A*A)-A) * (H*H/6.0);
+    D = ((B*B*B)-B) * (H*H/6.0);
+
+    Y = (A * y->data.F32[klo]) +
+        (B * y->data.F32[khi]) +
+        (C * (spline->p_psDeriv2)[klo]) +
+        (D * (spline->p_psDeriv2)[khi]);
+
+    return(Y);
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+/*****************************************************************************
+psVectorFitSpline1D(): given a psSpline1D data structure and a set of x/y
+vectors, this routine generates the linear or cublic splines which satisfy
+those data points.
+ 
+The formula for calculating the spline polynomials is derived from Numerical
+Recipes in C.  The basic idea is that the polynomial is
+ (1)     y = (A * y[0]) +
+ (2)         (B * y[1]) +
+ (3)         ((((A*A*A)-A) * mySpline->p_psDeriv2[0]) * H^2)/6.0 +
+ (4)         ((((B*B*B)-B) * mySpline->p_psDeriv2[1]) * H^2)/6.0
+Where:
+ H = x[1]-x[0]
+ A = (x[1]-x)/H
+ B = (x-x[0])/H
+The bulk of the code in this routine is the expansion of the above equation
+into a polynomial in terms of x, and then saving the coefficients of the
+powers of x in the spline polynomials.  This gets pretty complicated.
+ 
+XXX: usage of yErr is not specified in IfA documentation.
+XXX: Is the x argument redundant?  What do we do if the x argument is
+supplied, but does not equal the domains specified in mySpline?
+XXX: can psSpline be NULL?
+ 
+XXX: reimplement this assuming that mySpline is NULL?
+ 
+XXX: What happens if X is NULL, then an index vector is generated for X, but
+that index vector lies outside the range vectors in mySpline?
+ *****************************************************************************/
+psSpline1D *psVectorFitSpline1D(psSpline1D *mySpline,              ///< The spline which will be generated.
+                                const psVector* restrict x,        ///< Ordinates (or NULL to just use the indices)
+                                const psVector* restrict y,        ///< Coordinates
+                                const psVector* restrict yErr)     ///< Errors in coordinates, or NULL
+{
+    psTrace(".psLib.dataManip.psVectorFitSpline1D", 4,
+            "---- psVectorFitSpline1D() begin ----\n");
+    int numSplines = (y->n)-1;
+    float tmp;
+    float H;
+    int i;
+    float slope;
+    psVector *x32 = NULL;
+    psVector *y32 = NULL;
+    psVector *yErr32 = NULL;
+    static psVector *x32Static = NULL;
+    static psVector *y32Static = NULL;
+    static psVector *yErr32Static = NULL;
+
+    PS_CHECK_NULL_PTR_RETURN_NULL(mySpline);
+    PS_CHECK_NULL_PTR_RETURN_NULL(y);
+    VECTOR_CHECK_TYPE_F32_OR_F64_RETURN_NULL(y);
+    CONVERT_VECTOR_F64_TO_F32(y, y32, y32Static);
+
+    // If yErr==NULL, set all errors equal.
+    if (yErr == NULL) {
+        GEN_PERSIST_YERR_VEC_F32(yErr32Static, y->n);
+        yErr32 = yErr32Static;
+    } else {
+        VECTOR_CHECK_TYPE_F32_OR_F64_RETURN_NULL(yErr);
+        CONVERT_VECTOR_F64_TO_F32(yErr, yErr32, yErr32Static);
+    }
+
+    // If x==NULL, create an x32 vector with x values set to (0:n).
+    if (x == NULL) {
+        GEN_PERSIST_X_INDEX_VEC_F32(x32Static, y->n);
+        x32 = x32Static;
+    } else {
+        VECTOR_CHECK_TYPE_F32_OR_F64_RETURN_NULL(x);
+        CONVERT_VECTOR_F64_TO_F32(x, x32, x32Static);
+    }
+    PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(x32, y32);
+    PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(yErr32, y32);
+
+    if (y32->n != (1 + mySpline->n)) {
+        psError(__func__, "data size / spline size mismatch (%d %d)\n",
+                y32->n, mySpline->n);
+        return(NULL);
+    }
+
+    // If these are linear splines, which means their polynomials will have
+    // two coefficients, then we do the simple calculation.
+    if (2 == (mySpline->spline[0])->n) {
+        for (i=0;i<mySpline->n;i++) {
+            slope = (y32->data.F32[i+1] - y32->data.F32[i]) /
+                    (mySpline->domains[i+1] - mySpline->domains[i]);
+            (mySpline->spline[i])->coeff[0] = y32->data.F32[i] -
+                                              (slope * mySpline->domains[i]);
+
+            (mySpline->spline[i])->coeff[1] = slope;
+            psTrace(".psLib.dataManip.psMinimize.psVectorFitSpline1D", 4,
+                    "---- mySpline %d coeffs are (%f, %f)\n", i,
+                    (mySpline->spline[i])->coeff[0],
+                    (mySpline->spline[i])->coeff[1]);
+        }
+        psTrace(".psLib.dataManip.psMinimize.psVectorFitSpline1D", 4,
+                "---- Exiting psVectorFitSpline1D()()\n");
+        return((psSpline1D *) mySpline);
+    }
+
+    // Check if these are cubic splines (n==4).  If not, psError.
+    if (4 != (mySpline->spline[0])->n) {
+        psError(__func__, "Don't know how to generate %d-order splines.",
+                (mySpline->spline[0])->n-1);
+        return(NULL);
+    }
+
+    // If we get here, then we know these are cubic splines.  We first
+    // generate the second derivatives at each data point.
+    mySpline->p_psDeriv2 = CalculateSecondDerivs(x32, y32);
+    for (i=0;i<y32->n;i++)
+        psTrace(".psLib.dataManip.psVectorFitSpline1D", 6,
+                "Second deriv[%d] is %f\n", i, mySpline->p_psDeriv2[i]);
+
+    // We generate the coefficients of the spline polynomials.  I can't
+    // concisely explain how this code works.  See above function comments
+    // and Numerical Recipes in C.
+    for (i=0;i<numSplines;i++) {
+        H = x32->data.F32[i+1] - x32->data.F32[i];
+        psTrace(".psLib.dataManip.psVectorFitSpline1D", 4,
+                "x data (%f - %f) (%f)\n", x->data.F32[i], x->data.F32[i+1], H);
+        //
+        // ******** Calculate 0-order term ********
+        //
+        // From (1)
+        (mySpline->spline[i])->coeff[0] = (y32->data.F32[i] * x32->data.F32[i+1]/H);
+        // From (2)
+        ((mySpline->spline[i])->coeff[0])-= ((y32->data.F32[i+1] * x32->data.F32[i])/H);
+        // From (3)
+        tmp = (x32->data.F32[i+1] * x32->data.F32[i+1] * x32->data.F32[i+1]) / (H * H * H);
+        tmp-= (x32->data.F32[i+1] / H);
+        tmp*= (mySpline->p_psDeriv2)[i] * H * H / 6.0;
+        ((mySpline->spline[i])->coeff[0])+= tmp;
+        // From (4)
+        tmp = -(x32->data.F32[i] * x32->data.F32[i] * x32->data.F32[i]) / (H * H * H);
+        tmp+= (x32->data.F32[i] / H);
+        tmp*= (mySpline->p_psDeriv2)[i+1] * H * H / 6.0;
+        ((mySpline->spline[i])->coeff[0])+= tmp;
+
+        //
+        // ******** Calculate 1-order term ********
+        //
+        // From (1)
+        (mySpline->spline[i])->coeff[1] = -(y32->data.F32[i]) / H;
+        // From (2)
+        ((mySpline->spline[i])->coeff[1])+= (y32->data.F32[i+1] / H);
+        // From (3)
+        tmp = -3.0 * (x32->data.F32[i+1] * x32->data.F32[i+1]) / (H * H * H);
+        tmp+= (1.0 / H);
+        tmp*= ((mySpline->p_psDeriv2)[i]) * H * H / 6.0;
+        ((mySpline->spline[i])->coeff[1])+= tmp;
+        // From (4)
+        tmp = 3.0 * (x32->data.F32[i] * x32->data.F32[i]) / (H * H * H);
+        tmp-= (1.0 / H);
+        tmp*= ((mySpline->p_psDeriv2)[i+1]) * H * H / 6.0;
+        ((mySpline->spline[i])->coeff[1])+= tmp;
+
+        //
+        // ******** Calculate 2-order term ********
+        //
+        // From (3)
+        (mySpline->spline[i])->coeff[2] = ((mySpline->p_psDeriv2)[i]) * 3.0 * x32->data.F32[i+1] / (6.0 * H);
+        // From (4)
+        ((mySpline->spline[i])->coeff[2])-= (((mySpline->p_psDeriv2)[i+1]) * 3.0 * x32->data.F32[i] / (6.0 * H));
+
+        //
+        // ******** Calculate 3-order term ********
+        //
+        // From (3)
+        (mySpline->spline[i])->coeff[3] = -((mySpline->p_psDeriv2)[i]) / (6.0 * H);
+        // From (4)
+        ((mySpline->spline[i])->coeff[3])+=  ((mySpline->p_psDeriv2)[i+1]) / (6.0 * H);
+
+        psTrace(".psLib.dataManip.psVectorFitSpline1D", 6,
+                "(mySpline->spline[%d])->coeff[0] is %f\n", i, (mySpline->spline[i])->coeff[0]);
+        psTrace(".psLib.dataManip.psVectorFitSpline1D", 6,
+                "(mySpline->spline[%d])->coeff[1] is %f\n", i, (mySpline->spline[i])->coeff[1]);
+        psTrace(".psLib.dataManip.psVectorFitSpline1D", 6,
+                "(mySpline->spline[%d])->coeff[2] is %f\n", i, (mySpline->spline[i])->coeff[2]);
+        psTrace(".psLib.dataManip.psVectorFitSpline1D", 6,
+                "(mySpline->spline[%d])->coeff[3] is %f\n", i, (mySpline->spline[i])->coeff[3]);
+
+    }
+
+    psTrace(".psLib.dataManip.psVectorFitSpline1D", 4,
+            "---- psVectorFitSpline1D() end ----\n");
+    return(mySpline);
+}
+
+/******************************************************************************
+psMinimizeLMChi2():  This routine will take an procedure which calculates an
+arbitrary function and it's derivative and minimize the chi-squared match
+between that function at the specified coords and the specified value at
+those coords.
+ 
+XXX: Do this:
+ After checking that all entries in the paramMask are 1 or 0, when
+ forming the A matrix from alpha, try this:
+ 
+     A[i][i] = (1 + lambda*paramask[i]) * alpha[i][i];
+ 
+XXX: This is very different from what is specified in the SDR.  Must
+coordinate with IfA on new SDR.
+ 
+XXX: Do vector/image recycles.
+ 
+XXX: probably yErr will be part of the SDR.
+ 
+XXX: This must work for both F32 and F64.  F32 is currently implemented.
+     Note: since the LUD routines are only implemented in F64, then we
+     will have to convert all F32 input vectors to F64 regardless.  So,
+     the F64 port might be.
+ *****************************************************************************/
+bool psMinimizeLMChi2(psMinimization *min,
+                      psVector *params,
+                      const psVector *paramMask,
+                      psImage *covar,
+                      const psArray *coords,
+                      const psVector *value,
+                      psMinimizeLMChi2Func func)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(min);
+    PS_CHECK_NULL_VECTOR_RETURN_NULL(params);
+    PS_CHECK_EMPTY_VECTOR_RETURN_NULL(params);
+    PS_CHECK_NULL_PTR_RETURN_NULL(coords);
+    PS_CHECK_NULL_VECTOR_RETURN_NULL(value);
+    PS_CHECK_EMPTY_VECTOR_RETURN_NULL(value);
+    if (paramMask != NULL) {
+        PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(params, paramMask);
+    }
+    psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
+            "---- psMinimizeLMChi2() begin ----\n");
+    int numData = value->n;
+    int numParams = params->n;
+    int i;
+    int j;
+    int k;
+    int l;
+    int n;
+    int p;
+    psVector *beta = psVectorAlloc(numParams, PS_TYPE_F64);
+    psVector *perm = psVectorAlloc(numParams, PS_TYPE_F64);
+
+    psVector *paramDeltasF64 = psVectorAlloc(numParams, PS_TYPE_F64);
+    psVector *origParams = psVectorAlloc(numParams, PS_TYPE_F32);
+    psVector *newParams = psVectorAlloc(numParams, PS_TYPE_F32);
+
+    psImage *alpha = psImageAlloc(numParams, numParams, PS_TYPE_F32);
+    psImage *A = psImageAlloc(numParams, numParams, PS_TYPE_F64);
+    psImage *aOut = psImageAlloc(numParams, numParams, PS_TYPE_F64);
+
+    psVector **deriv = (psVector **) psAlloc(numData * sizeof(psVector *));
+    for (i=0;i<numData;i++) {
+        deriv[i] = psVectorAlloc(numParams, PS_TYPE_F32);
+    }
+
+    psVector *currValueVec = psVectorAlloc(value->n, PS_TYPE_F32);
+    psVector *newValueVec = psVectorAlloc(value->n, PS_TYPE_F32);
+
+    float currChi2 = 0.0;
+    float newChi2 = 0.0;
+    float lamda = 0.00005;
+
+    psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
+            "min->maxIter is %d\n", min->maxIter);
+    psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
+            "min->tol is %f\n", min->tol);
+
+    for (p=0;p<numParams;p++) {
+        origParams->data.F32[p] = params->data.F32[p];
+    }
+
+    min->lastDelta = HUGE;
+    min->iter = 0;
+
+    while ((min->lastDelta > min->tol) && (min->iter < min->maxIter)) {
+        psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
+                "------------------------------------------------------\n");
+        psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
+                "Iteration %d.  Delta is %f\n", min->iter, min->lastDelta);
+
+        //
+        // Calculate the current values and chi-squared of the function.
+        //
+        currChi2 = 0.0;
+        for (n=0;n<numData;n++) {
+            currValueVec->data.F32[n] = func(deriv[n],
+                                             params,
+                                             (psVector *) coords->data[n]);
+            currChi2+= (currValueVec->data.F32[n] * currValueVec->data.F32[n]);
+        }
+
+        for (p=0;p<numParams;p++) {
+            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
+                    "params->data.F32[%d] is %f.\n", p, params->data.F32[p]);
+        }
+        psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
+                "Current chi-squared is (%f)\n", currChi2);
+
+        //
+        // Mask elements of the derivative for each data point.
+        //
+        for (p=0;p<numParams;p++) {
+            if ((paramMask != NULL) && (paramMask->data.U8[p] != 0)) {
+                for (n=0;n<numData;n++) {
+                    (deriv[n])->data.F32[p] = 0.0;
+                }
+            }
+        }
+
+        //
+        // Calculate the BETA vector.
+        //
+        for (p=0;p<numParams;p++) {
+            beta->data.F64[p] = 0.0;
+            for (n=0;n<numData;n++) {
+                (beta->data.F64[p])+=
+                    (value->data.F32[n] - currValueVec->data.F32[n]) *
+                    (deriv[n])->data.F32[p];
+            }
+            // XXX: multiple by -1 here?
+            (beta->data.F64[p])*= -1.0;
+            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
+                    "beta->data.F64[%d] is %f.\n", p, beta->data.F64[p]);
+        }
+
+        //
+        // Calculate the ALPHA matrix.
+        //
+        for (k=0;k<numParams;k++) {
+            for (l=0;l<numParams;l++) {
+                alpha->data.F32[k][l] = 0.0;
+                for (n=0;n<numData;n++) {
+                    alpha->data.F32[k][l]+= (deriv[n])->data.F32[k] *
+                                            (deriv[n])->data.F32[l];
+                }
+            }
+        }
+
+        //
+        // Calculate the matrix A.
+        //
+        for (j=0;j<numParams;j++) {
+            for (k=0;k<numParams;k++) {
+                if (j == k) {
+                    A->data.F64[j][k] =
+                        (double) ((1.0 + lamda) * alpha->data.F32[j][k]);
+                } else {
+                    A->data.F64[j][k] = (double) alpha->data.F32[j][k];
+                }
+            }
+        }
+        for (j=0;j<numParams;j++) {
+            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "Matrix A[][]:\n");
+            for (k=0;k<numParams;k++) {
+                psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "%f ", A->data.F64[j][k]);
+            }
+            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6, "Matrix A[][]:\n");
+        }
+
+        //
+        // Solve A * alpha = Beta
+        //
+        aOut = psMatrixLUD(aOut, perm, A);
+        paramDeltasF64 = psMatrixLUSolve(paramDeltasF64, aOut, beta, perm);
+
+        //
+        // Mask any masked parameters.
+        //
+        for (i=0;i<numParams;i++) {
+            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
+                    "paramDeltasF64->data.F64[%d] is %f.\n", i, paramDeltasF64->data.F64[i]);
+            if ((paramMask != NULL) && (paramMask->data.U8[i] != 0)) {
+                newParams->data.F32[i] = origParams->data.F32[i];
+            } else {
+                newParams->data.F32[i] = params->data.F32[i] -
+                                         (float) paramDeltasF64->data.F64[i];
+            }
+        }
+
+        psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
+                "Calling func() with new parameters:\n");
+        for (i=0;i<numParams;i++) {
+            psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,
+                    "newParams->data.F32[%d] is %f.\n", i, newParams->data.F32[i]);
+        }
+
+
+        //
+        // Calculate new function values.
+        //
+        newChi2 = 0.0;
+        for (n=0;n<numData;n++) {
+            newValueVec->data.F32[n] = func(deriv[n], newParams,
+                                            (psVector *) coords->data[n]);
+            newChi2+= (newValueVec->data.F32[n] * newValueVec->data.F32[n]);
+        }
+        psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
+                "old/new chi-squareds are (%f, %f)\n", currChi2, newChi2);
+
+        //
+        // If the new chi-squared is lower, then keep it.
+        //
+        if (currChi2 > newChi2) {
+            min->lastDelta = currChi2 - newChi2;
+            min->value = newChi2;
+
+            // We already masked params.
+            for (i=0;i<numParams;i++) {
+                params->data.F32[i] = (float) newParams->data.F32[i];
+            }
+            lamda*= 0.1;
+        } else {
+            lamda*= 10.0;
+        }
+        psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
+                "lamda is %f\n", lamda);
+        min->iter++;
+    }
+    psFree(beta);
+    psFree(perm);
+    psFree(paramDeltasF64);
+    psFree(origParams);
+    psFree(newParams);
+    psFree(alpha);
+    psFree(A);
+    psFree(aOut);
+    for (i=0;i<numData;i++) {
+        psFree(deriv[i]);
+    }
+    psFree(deriv);
+    psFree(currValueVec);
+    psFree(newValueVec);
+
+    if ((min->iter < min->maxIter) ||
+            (min->lastDelta <= min->tol)) {
+        return(true);
+    }
+
+    psTrace(".psLib.dataManip.psMinimizeLMChi2", 4,
+            "---- psMinimizeLMChi2() end (false) ----\n");
+    return(false);
+}
+
+/******************************************************************************
+p_psVectorFitPolynomial1DCheb():  This routine will fit a Chebyshev
+polynomial of degree myPoly to the data points (x, y) and return the
+coefficients of that polynomial.
+ 
+XXX: yErr is currently ignored.
+ 
+XXX: Use private name?
+*****************************************************************************/
+psPolynomial1D *p_psVectorFitPolynomial1DCheby(psPolynomial1D* myPoly,
+        const psVector* restrict x,
+        const psVector* restrict y,
+        const psVector* restrict yErr)
+{
+    int j;
+    int k;
+    int n = x->n;
+    double fac;
+    double sum;
+    GEN_STATIC_RECYCLED_VECTOR(f, n, PS_TYPE_F64);
+    psScalar *fScalar;
+    psScalar tmpScalar;
+    tmpScalar.type.type = PS_TYPE_F64;
+
+    // XXX: These assignments appear too simple to warrant code and
+    // variable declarations.  I retain them here to maintain coherence
+    // with the NR code.
+    double min = -1.0;
+    double max = 1.0;
+    double bma = 0.5 * (max-min);  // 1
+    double bpa = 0.5 * (max+min);  // 0
+
+    // In this loop, we first calculate the values of X for which the
+    // Chebyshev polynomials are zero (see NR, section 5.4).  Then we
+    // calculate the value of the function we are fitting the Chebyshev
+    // polynomials to at those values of X.  This is a bit tricky since
+    // we don't know that function.  So, we instead do 3-order LaGrange
+    // interpolation at the point X for the psVectors x,y for which we
+    // are fitting this ChebyShev polynomial to.
+
+    for (int i=0;i<n;i++) {
+        // NR 5.8.4
+        double Y = cos(M_PI * (0.5 + ((float) i)) / ((float) n));
+        double X = (Y + bma + bpa) - 1.0;
+        tmpScalar.data.F64 = X;
+
+        // We interpolate against are tabluated x,y vectors to determine the
+        // function value at X.
+        fScalar = p_psVectorInterpolate((psVector *) x,
+                                        (psVector *) y,
+                                        3,
+                                        &tmpScalar);
+
+        f->data.F64[i] = fScalar->data.F64;
+        psFree(fScalar);
+
+        psTrace(".psLib.dataManip.p_psVectorFitPolynomial1DCheby", 6,
+                "(x, X, y, f(X)) is (%f, %f, %f, %f)\n",
+                x->data.F64[i], X, y->data.F64[i], f->data.F64[i]);
+    }
+
+    // We have the values for f() at the zero points, we now calculate the
+    // coefficients of the Chebyshev polynomial: NR 5.8.7.
+
+    fac = 2.0/((float) n);
+    // XXX: is this loop bound correct?
+    for (j=0;j<myPoly->n;j++) {
+        sum = 0.0;
+        for (k=0;k<n;k++) {
+            sum+= f->data.F64[k] *
+                  cos(M_PI * ((float) j) * (0.5 + ((float) k)) / ((float) n));
+        }
+
+        myPoly->coeff[j] = fac * sum;
+    }
+
+    return(myPoly);
+}
+
+/******************************************************************************
+p_psVectorFitPolynomial1DOrd():  This routine will fit an ordinary
+polynomial of degree myPoly to the data points (x, y) and return the
+coefficients of that polynomial.
+ 
+XXX: Use private name?
+XXX: Use recycled vectors.
+ *****************************************************************************/
+psPolynomial1D* p_psVectorFitPolynomial1DOrd(psPolynomial1D* myPoly,
+        const psVector* restrict x,
+        const psVector* restrict y,
+        const psVector* restrict yErr)
+{
+    int polyOrder = myPoly->n;
+    psImage* A = NULL;
+    psImage* ALUD = NULL;
+    psVector* B = NULL;
+    psVector* outPerm = NULL;
+    psVector* X = NULL;         // NOTE: do we need this?
+    psVector* coeffs = NULL;
+    int i = 0;
+    int j = 0;
+    int k = 0;
+    psVector* xSums = NULL;
+
+    psTrace(".psLib.dataManip.psVectorFitPolynomial1D", 4,
+            "---- psVectorFitPolynomial1D() begin ----\n");
+    // printf("psVectorFitPolynomial1D()\n");
+    // for (i=0;i<x->n;i++) {
+    // printf("(x, y, yErr) is (%f, %f, %f)\n", x->data.F64[i], y->data.F64[i], yErr->data.F64[i]);
+    // }
+
+    A = psImageAlloc(polyOrder, polyOrder, PS_TYPE_F64);
+    ALUD = psImageAlloc(polyOrder, polyOrder, PS_TYPE_F64);
+    B = psVectorAlloc(polyOrder, PS_TYPE_F64);
+    coeffs = psVectorAlloc(polyOrder, PS_TYPE_F64);
+    X = psVectorAlloc(x->n, PS_TYPE_F64);
+    outPerm = psVectorAlloc(polyOrder, PS_TYPE_F64);
+    xSums = psVectorAlloc(1 + 2 * polyOrder, PS_TYPE_F64);
+
+    // Initialize data structures.
+    for (i = 0; i < polyOrder; i++) {
+        B->data.F64[i] = 0.0;
+        coeffs->data.F64[i] = 0.0;
+        outPerm->data.F64[i] = 0.0;
+        for (j = 0; j < polyOrder; j++) {
+            A->data.F64[i][j] = 0.0;
+            ALUD->data.F64[i][j] = 0.0;
+        }
+    }
+    for (i = 0; i < X->n; i++) {
+        X->data.F64[i] = x->data.F64[i];
+    }
+
+    // Build the B and A data structs.
+    if (yErr == NULL) {
+        for (i = 0; i < X->n; i++) {
+            p_psBuildSums1D(X->data.F64[i], 2 * polyOrder, xSums);
+
+            for (k = 0; k < polyOrder; k++) {
+                B->data.F64[k] += y->data.F64[i] * xSums->data.F64[k];
+            }
+
+            for (k = 0; k < polyOrder; k++) {
+                for (j = 0; j < polyOrder; j++) {
+                    A->data.F64[k][j] += xSums->data.F64[k + j];
+                }
+            }
+        }
+    } else {
+        for (i = 0; i < X->n; i++) {
+            p_psBuildSums1D(X->data.F64[i], 2 * polyOrder, xSums);
+
+            for (k = 0; k < polyOrder; k++) {
+                B->data.F64[k] += y->data.F64[i] * xSums->data.F64[k] /
+                                  yErr->data.F64[i];
+            }
+
+            for (k = 0; k < polyOrder; k++) {
+                for (j = 0; j < polyOrder; j++) {
+                    A->data.F64[k][j] += xSums->data.F64[k + j] /
+                                         yErr->data.F64[i];
+                }
+            }
+        }
+    }
+
+    ALUD = psMatrixLUD(ALUD, outPerm, A);
+    coeffs = psMatrixLUSolve(coeffs, ALUD, B, outPerm);
+
+    for (k = 0; k < polyOrder; k++) {
+        myPoly->coeff[k] = coeffs->data.F64[k];
+        // printf("myPoly->coeff[%d] is %f\n", k, myPoly->coeff[k]);
+    }
+
+    // for (i=0;i<x->n;i++) {
+    // printf("HMMM: psEvalPolynomial1D(%f) is %f\n", x->data.F64[i], psEvalPolynomial1D(x->data.F64[i],
+    // myPoly));
+    // }
+
+    psFree(A);
+    psFree(ALUD);
+    psFree(B);
+    psFree(coeffs);
+    psFree(X);
+    psFree(outPerm);
+    psFree(xSums);
+
+    psTrace(".psLib.dataManip.psVectorFitPolynomial1D", 4,
+            "---- psVectorFitPolynomial1D() begin ----\n");
+    return (myPoly);
+}
+
+/******************************************************************************
+psVectorFitPolynomial1D():  This routine must fit a polynomial of degree
+myPoly to the data points (x, y) and return the coefficients of that
+polynomial.
+ 
+XXX: type F32 is done via vector conversion only.
+ *****************************************************************************/
+psPolynomial1D* psVectorFitPolynomial1D(psPolynomial1D* myPoly,
+                                        const psVector* restrict x,
+                                        const psVector* restrict y,
+                                        const psVector* restrict yErr)
+{
+    int i;
+    psPolynomial1D *tmpPoly;
+    PS_CHECK_NULL_1DPOLY_RETURN_NULL(myPoly);
+    PS_CHECK_NULL_VECTOR_RETURN_NULL(y);
+    PS_CHECK_EMPTY_VECTOR_RETURN_NULL(y);
+    psVector *x64 = NULL;
+    psVector *y64 = NULL;
+    psVector *yErr64 = NULL;
+    static psVector *x64Static = NULL;
+    static psVector *y64Static = NULL;
+    static psVector *yErr64Static = NULL;
+
+    VECTOR_CHECK_TYPE_F32_OR_F64_RETURN_NULL(y);
+    CONVERT_VECTOR_F32_TO_F64(y, y64, y64Static);
+
+    // If yErr==NULL, set all errors equal.
+    if (yErr == NULL) {
+        GEN_PERSIST_YERR_VEC_F64(yErr64Static, y->n);
+        yErr64 = yErr64Static;
+    } else {
+        VECTOR_CHECK_TYPE_F32_OR_F64_RETURN_NULL(yErr);
+        CONVERT_VECTOR_F32_TO_F64(yErr, yErr64, yErr64Static);
+    }
+
+    // If x==NULL, create an x64 vector with x values set to (0:n).
+    if (x == NULL) {
+        GEN_PERSIST_X_INDEX_VEC_F64(x64Static, y->n);
+        if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+            p_psNormalizeVector(x64Static);
+        }
+        x64 = x64Static;
+    } else {
+        VECTOR_CHECK_TYPE_F32_OR_F64_RETURN_NULL(x);
+        CONVERT_VECTOR_F32_TO_F64(x, x64, x64Static);
+    }
+    PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(x64, y64);
+    PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(yErr64, y64);
+
+    // Call the appropriate vector fitting routine.
+    if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        p_psVectorFitPolynomial1DCheby(myPoly, x64, y64, yErr64);
+    } else if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        tmpPoly = p_psVectorFitPolynomial1DOrd(myPoly, x64, y64, yErr64);
+    } else {
+        psError(__func__, "unknown polynomial type.\n");
+        return(NULL);
+    }
+
+    return(myPoly);
+}
+
+
+
+/******************************************************************************
+ *****************************************************************************/
+psMinimization *psMinimizationAlloc(int maxIter,
+                                    float tol)
+{
+    psMinimization *min = psAlloc(sizeof(psMinimization));
+    min->maxIter = maxIter;
+    min->tol = tol;
+    min->value = 0.0;
+    min->iter = 0;
+    min->lastDelta = 0.0;
+
+    return(min);
+}
+
+/******************************************************************************
+p_psDetermineBracket():  This routine takes as input an arbitrary function,
+and the parameter to vary, and the line along which it must vary.  This
+function produces as output a bracket [a, b, c] such that
+ 
+        f(param + b * line) is less than f(param + a * line) and
+                                         f(param + c * line).
+ 
+Algorithm: XXX completely ad hoc: start with the user-supplied starting
+parameter and call that b.  Calculate a/c as a fractional amount
+smaller/larger than b.  Repeat this process until a local minimum is found.
+ 
+XXX: new algorithm: start at x=0, expand in one direction until the function
+decreases.  Then you have two points in the bracket.  Keep going until it
+increases, or x is too large.  If thst does not work, expand in the other
+direction.
+ 
+XXX: This is F32 only
+ *****************************************************************************/
+psVector *p_psDetermineBracket(psVector *params,
+                               psVector *line,
+                               const psVector *paramMask,
+                               const psArray *coords,
+                               psMinimizePowellFunc func)
+{
+    float a = 0.0;
+    float b = 0.0;
+    float c = 0.0;
+    float fa = 0.0;
+    float fb = 0.0;
+    float fc = 0.0;
+    int iter = 100;
+    float aDir = 0.0;
+    float cDir = 0.0;
+    float new_aDir = 0.0;
+    float new_cDir = 0.0;
+    psVector *bracket = psVectorAlloc(3, PS_TYPE_F32);
+    float stepSize = DETERMINE_BRACKET_STEP_SIZE;
+    psVector *tmp = NULL;
+    int i = 0;
+    int null = 0;
+
+    psTrace(".psLib.dataManip.p_psDetermineBracket", 4,
+            "---- p_psDetermineBracket() begin ----\n");
+
+    for (i=0;i<params->n;i++) {
+        if (paramMask->data.U8[i] == 0) {
+            if (line->data.F32[i] >= FLT_EPSILON) {
+                null = 1;
+            }
+        }
+    }
+
+    if (null == 0) {
+        psTrace(".psLib.dataManip.p_psDetermineBracket", 2,
+                "p_psDetermineBracket() called with zero line vector.\n");
+        psTrace(".psLib.dataManip.p_psDetermineBracket", 4,
+                "---- p_psDetermineBracket() end (NULL) ----\n");
+        psFree(bracket);
+        return(NULL);
+    }
+
+    tmp = psVectorAlloc(params->n, PS_TYPE_F32);
+
+    b = 0;
+    a = -stepSize;
+    c = stepSize;
+
+    for (i=0;i<params->n;i++) {
+        if (paramMask->data.U8[i] == 0) {
+            tmp->data.F32[i] = params->data.F32[i] + (a * line->data.F32[i]);
+        } else {
+            tmp->data.F32[i] = params->data.F32[i];
+        }
+    }
+    fa = func(tmp, coords);
+
+    for (i=0;i<params->n;i++) {
+        if (paramMask->data.U8[i] == 0) {
+            tmp->data.F32[i] = params->data.F32[i] + (b * line->data.F32[i]);
+        } else {
+            tmp->data.F32[i] = params->data.F32[i];
+        }
+    }
+    fb = func(tmp, coords);
+
+    for (i=0;i<params->n;i++) {
+        if (paramMask->data.U8[i] == 0) {
+            tmp->data.F32[i] = params->data.F32[i] + (c * line->data.F32[i]);
+        } else {
+            tmp->data.F32[i] = params->data.F32[i];
+        }
+    }
+    fc = func(tmp, coords);
+
+    if (fa < fb) {
+        aDir = -1;
+    } else {
+        aDir = 1;
+    }
+
+    if (fc < fb) {
+        cDir = -1;
+    } else {
+        cDir = 1;
+    }
+
+    psTrace(".psLib.dataManip.p_psDetermineBracket", 6,
+            "(a, b, c) is (%f %f %f) (fa, fb, fc) is (%f %f %f)\n", a, b, c, fa, fb, fc);
+
+    while (iter > 0) {
+        psTrace(".psLib.dataManip.p_psDetermineBracket", 6,
+                "psDetermineBracket(): iteration %d\n", iter);
+        if ((fb < fa) && (fb < fc)) {
+            bracket->data.F32[0] = a;
+            bracket->data.F32[1] = b;
+            bracket->data.F32[2] = c;
+            psFree(tmp);
+            psTrace(".psLib.dataManip.p_psDetermineBracket", 6,
+                    "---- p_psDetermineBracket() end ----\n");
+            return(bracket);
+        }
+        stepSize*= (1.0 + stepSize);
+        a =- stepSize;
+        c =+ stepSize;
+
+        for (i=0;i<params->n;i++) {
+            if (paramMask->data.U8[i] == 0) {
+                tmp->data.F32[i] = params->data.F32[i] + (a * line->data.F32[i]);
+            } else {
+                tmp->data.F32[i] = params->data.F32[i];
+            }
+        }
+        fa = func(tmp, coords);
+
+        for (i=0;i<params->n;i++) {
+            if (paramMask->data.U8[i] == 0) {
+                tmp->data.F32[i] = params->data.F32[i] + (c * line->data.F32[i]);
+            } else {
+                tmp->data.F32[i] = params->data.F32[i];
+            }
+        }
+        fc = func(tmp, coords);
+
+        psTrace(".psLib.dataManip.p_psDetermineBracket", 6,
+                "Iter(%d): (a, b, c) is (%f %f %f) (fa, fb, fc) is (%f %f %f)\n", iter, a, b, c, fa, fb, fc);
+
+        if (fa < fb) {
+            new_aDir = -1;
+        } else {
+            new_aDir = 1;
+        }
+
+        if (fc < fb) {
+            new_cDir = -1;
+        } else {
+            new_cDir = 1;
+        }
+        if ((new_aDir == 1) && (aDir == -1)) {
+            bracket->data.F32[0] = a;
+            bracket->data.F32[1] = b;
+            bracket->data.F32[2] = c;
+            psFree(tmp);
+            psTrace(".psLib.dataManip.p_psDetermineBracket", 4,
+                    "---- p_psDetermineBracket() end ----\n");
+            return(bracket);
+        }
+
+        if ((new_cDir == 1) && (cDir == -1)) {
+            bracket->data.F32[0] = a;
+            bracket->data.F32[1] = b;
+            bracket->data.F32[2] = c;
+            psFree(tmp);
+            psTrace(".psLib.dataManip.p_psDetermineBracket", 4,
+                    "---- p_psDetermineBracket() end ----\n");
+            return(bracket);
+        }
+        aDir = new_aDir;
+        cDir = new_cDir;
+        iter--;
+    }
+    psFree(tmp);
+    psFree(bracket);
+    psTrace(".psLib.dataManip.p_psDetermineBracket", 4,
+            "---- p_psDetermineBracket() end (NULL) ----\n");
+    return(NULL);
+}
+
+/******************************************************************************
+This routine takes as input a possibly multi-dimensional function, along
+with an initial guess at the parameters of that function and vector "line"
+of the same size as the parameter vector.  It will minimize the function
+along that vector anr returns the offset along that vector at which the
+minimum is determined.
+ 
+XXX: This routine is not very efficient in terms of total evaluations of the
+function.
+XXX: This is F32 only
+ *****************************************************************************/
+float p_psLineMin(psMinimization *min,
+                  psVector *params,
+                  psVector *line,
+                  const psVector *paramMask,
+                  const psArray *coords,
+                  psMinimizePowellFunc func)
+{
+    psVector *bracket;
+    float a = 0.0;
+    float b = 0.0;
+    float c = 0.0;
+    float n = 0.0;
+    float fa = 0.0;
+    float fb = 0.0;
+    float fc = 0.0;
+    float fn = 0.0;
+    float mul = 0.0;
+    psVector *tmpa = NULL;
+    psVector *tmpb = NULL;
+    psVector *tmpc = NULL;
+    psVector *tmpn = NULL;
+    int i = 0;
+    int null = 0;
+
+    psTrace(".psLib.dataManip.p_psLineMin", 4,
+            "---- p_psLineMin() begin ----\n");
+    psTrace(".psLib.dataManip.p_psLineMin", 6,
+            "min->maxIter is %d\n", min->maxIter);
+    psTrace(".psLib.dataManip.p_psLineMin", 6,
+            "min->tol is %f\n", min->tol);
+
+    if (paramMask != NULL) {
+        for (i=0;i<params->n;i++) {
+            if (paramMask->data.U8[i] == 0) {
+                if (line->data.F32[i] >= FLT_EPSILON) {
+                    null = 1;
+                    psTrace(".psLib.dataManip.p_psLineMin", 4,
+                            "line->data.F32[%d] is %f\n", i, line->data.F32[i]);
+                }
+            }
+        }
+    } else {
+        for (i=0;i<params->n;i++) {
+            if (line->data.F32[i] >= FLT_EPSILON) {
+                null = 1;
+                psTrace(".psLib.dataManip.p_psLineMin", 4,
+                        "line->data.F32[%d] is %f\n", i, line->data.F32[i]);
+            }
+        }
+    }
+
+    if (null == 0) {
+        psTrace(".psLib.dataManip.p_psLineMin", 2,
+                "p_psLineMin() called with zero line vector.\n");
+        return(0.0);
+    }
+
+    tmpa = psVectorAlloc(params->n, PS_TYPE_F32);
+    tmpb = psVectorAlloc(params->n, PS_TYPE_F32);
+    tmpc = psVectorAlloc(params->n, PS_TYPE_F32);
+    tmpn = psVectorAlloc(params->n, PS_TYPE_F32);
+
+    for (i=0;i<params->n;i++) {
+        psTrace(".psLib.dataManip.p_psLineMin", 6,
+                "params, paramMask, line [%d] is (%f %d %f)\n", i,
+                params->data.F32[i],
+                paramMask->data.U8[i],
+                line->data.F32[i]);
+    }
+
+    bracket = p_psDetermineBracket(params, line, paramMask, coords, func);
+    if (bracket == NULL) {
+        psFree(tmpa);
+        psFree(tmpb);
+        psFree(tmpc);
+        psFree(tmpn);
+        psAbort(__func__, "(1) Could not bracket minimum.");
+    }
+
+    min->iter = 0;
+    while (min->iter < min->maxIter) {
+        min->iter++;
+        psTrace(".psLib.dataManip.p_psLineMin", 6,
+                "p_psLineMin(): iteration %d\n", min->iter);
+
+        a = bracket->data.F32[0];
+        b = bracket->data.F32[1];
+        c = bracket->data.F32[2];
+
+        for (i=0;i<params->n;i++) {
+            if (paramMask->data.U8[i] == 0) {
+                tmpa->data.F32[i] = params->data.F32[i] + (a * line->data.F32[i]);
+                tmpb->data.F32[i] = params->data.F32[i] + (b * line->data.F32[i]);
+                tmpc->data.F32[i] = params->data.F32[i] + (c * line->data.F32[i]);
+            } else {
+                tmpa->data.F32[i] = params->data.F32[i];
+                tmpb->data.F32[i] = params->data.F32[i];
+                tmpc->data.F32[i] = params->data.F32[i];
+            }
+        }
+        fa = func(tmpa, coords);
+        fb = func(tmpb, coords);
+        fc = func(tmpc, coords);
+        psTrace(".psLib.dataManip.p_psLineMin", 6,
+                "Iteration %d: f(%f %f %f) is (%f %f %f)\n", min->iter,
+                a, b, c, fa, fb, fc);
+
+        // We determine which is the biggest segment in [a,b,c] then split
+        // that with the point n.
+        if ((b-a) > (c-b)) {
+            // This is the golden section formula
+            n = a + (0.69 * (b-a));
+            for (i=0;i<params->n;i++) {
+                tmpn->data.F32[i] = params->data.F32[i] + (n * line->data.F32[i]);
+            }
+            fn = func(tmpn, coords);
+
+            if (fn > fb) {
+                // a = n, b = b, c = c
+                bracket->data.F32[0] = n;
+            } else {
+                // a = a, b = n, c = b
+                bracket->data.F32[1] = n;
+                bracket->data.F32[2] = b;
+            }
+        } else {
+            n = b + (0.69 * (c-b));
+            for (i=0;i<params->n;i++) {
+                tmpn->data.F32[i] = params->data.F32[i] + (n * line->data.F32[i]);
+            }
+            fn = func(tmpn, coords);
+
+            if (fn > fb) {
+                // a = a, b = b, c = n
+                bracket->data.F32[2] = n;
+            } else {
+                // a = b, b = n, c = c
+                bracket->data.F32[0] = b;
+                bracket->data.F32[1] = n;
+            }
+        }
+        psTrace(".psLib.dataManip.p_psLineMin", 6,
+                "Iteration %d: new bracket is (%f %f %f)\n", min->iter, bracket->data.F32[0], bracket->data.F32[1], bracket->data.F32[2]);
+
+        mul = bracket->data.F32[1];
+        if ((fabs(a-b) < min->tol) && (fabs(b-c) < min->tol)) {
+            for (i=0;i<params->n;i++) {
+                if (paramMask->data.U8[i] == 0) {
+                    params->data.F32[i]+= mul * line->data.F32[i];
+                }
+            }
+            min->value = func(params, coords);
+            psFree(bracket);
+            psFree(tmpa);
+            psFree(tmpb);
+            psFree(tmpc);
+            psFree(tmpn);
+            psTrace(".psLib.dataManip.p_psLineMin", 4,
+                    "---- p_psLineMin() end.a (%f) ----\n", mul);
+            return(mul);
+        }
+    }
+
+    psFree(bracket);
+    psFree(tmpa);
+    psFree(tmpb);
+    psFree(tmpc);
+    psFree(tmpn);
+
+    psTrace(".psLib.dataManip.p_psLineMin", 4,
+            "---- p_psLineMin() end.b (0.0) ----\n");
+    return(0.0);
+}
+
+
+/******************************************************************************
+This routine must minimize a possibly multi-dimensional function.  The
+function to be minimized "func" is:
+    float func(psVector *params, psArray *coords)
+The "params" are the parameters of the function which are varied.  The data
+points at which the function is varied are in the argument "coords" which is
+a psArray of psVectors: each vector represents a different coordinate.
+ 
+XXX: We do not use Brent's method.
+ 
+XXX: The SDR is silent about data types.  F32 is implemented here.
+ 
+XXX: Define constants for default dummy number of iterations and tolerance.
+ 
+XXX: Must define behavior on various NULL inputs.
+ 
+XXX: Check for F32 types?
+ *****************************************************************************/
+bool psMinimizePowell(psMinimization *min,
+                      psVector *params,
+                      const psVector *paramMask,
+                      const psArray *coords,
+                      psMinimizePowellFunc func)
+{
+    PS_CHECK_NULL_VECTOR_RETURN_NULL(params);
+    PS_CHECK_EMPTY_VECTOR_RETURN_NULL(params);
+    PS_CHECK_NULL_PTR_RETURN_NULL(min);
+    PS_CHECK_NULL_PTR_RETURN_NULL(coords);
+    PS_CHECK_NULL_PTR_RETURN_NULL(func);
+
+    int numDims = params->n;
+    int i = 0;
+    int j = 0;
+    psVector **v = NULL;
+    psVector *pQP = NULL;
+    psVector *Q = NULL;
+    psVector *u = NULL;
+    psVector *myParamMask = NULL;  // XXX: Use a recylced vector here.
+    psMinimization dummyMin;
+    float mul = 0.0;
+    float baseFuncVal = 0.0;
+    float currFuncVal = 0.0;
+    int biggestIter = 0;
+    float biggestDiff = 0.0;
+    float term1 = 0.0;
+    float term2 = 0.0;
+    float fqp = 0.0;
+    float diff = 0.0;
+
+    psTrace(".psLib.dataManip.psMinimizePowell", 4,
+            "---- psMinimizePowell() begin ----\n");
+    psTrace(".psLib.dataManip.psMinimizePowell", 6,
+            "min->maxIter is %d\n", min->maxIter);
+    psTrace(".psLib.dataManip.psMinimizePowell", 6,
+            "min->tol is %f\n", min->tol);
+
+    pQP = psVectorAlloc(numDims, PS_TYPE_F32);
+    u = psVectorAlloc(numDims, PS_TYPE_F32);
+    Q = psVectorAlloc(numDims, PS_TYPE_F32);
+
+    if (paramMask == NULL) {
+        myParamMask = psVectorAlloc(params->n, PS_TYPE_U8);
+        for (i=0;i<myParamMask->n;i++) {
+            myParamMask->data.U8[i] = 0;
+        }
+    } else {
+        myParamMask = (psVector *) paramMask;
+    }
+    PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(params, myParamMask);
+
+    // 1: Set v[i] to be the unit vectors for each dimension in params
+    v = (psVector **) psAlloc(params->n * sizeof(psVector **));
+    for (i=0;i<numDims;i++) {
+        v[i] = psVectorAlloc(numDims, PS_TYPE_F32);
+        for (j=0;j<numDims;j++) {
+            if (i == j) {
+                v[i]->data.F32[j] = 1.0;
+            } else {
+                v[i]->data.F32[j] = 0.0;
+            }
+        }
+    }
+
+    // 2: Set Q to be the initial params (P in the ADD)
+    for (i=0;i<numDims;i++) {
+        if (myParamMask->data.U8[i] == 0) {
+            Q->data.F32[i] = params->data.F32[i];
+        }
+    }
+
+    min->iter = 0;
+    while (min->iter < min->maxIter) {
+        min->iter++;
+        psTrace(".psLib.dataManip.psMinimizePowell", 6,
+                "psMinimizePowell() iteration %d\n", min->iter);
+
+        // 3: For each dimension in params, move Q only in the vector v[i] to
+        //    minimize the function.
+
+        baseFuncVal = func(Q, coords);
+        currFuncVal = baseFuncVal;
+        diff = 0.0;
+        biggestDiff = 0;
+        biggestIter = 0;
+        for (i=0;i<numDims;i++) {
+            if (myParamMask->data.U8[i] == 0) {
+                dummyMin.maxIter = 100;
+                dummyMin.tol = 0.01;
+                mul = p_psLineMin(&dummyMin, Q, v[i], myParamMask, coords, func);
+                if (fabs(dummyMin.value - currFuncVal) > biggestDiff) {
+                    biggestDiff = fabs(dummyMin.value - currFuncVal);
+                    biggestIter = i;
+                }
+                currFuncVal = dummyMin.value;
+            }
+        }
+
+        // 4: Set the vector u = Q - P
+        for (i=0;i<numDims;i++) {
+            if (myParamMask->data.U8[i] == 0) {
+                u->data.F32[i] = Q->data.F32[i] - params->data.F32[i];
+
+                psTrace(".psLib.dataManip.psMinimizePowell", 6,
+                        "u=Q-P (%f = %f - %f)\n", u->data.F32[i],
+                        Q->data.F32[i],
+                        params->data.F32[i]);
+
+            } else {
+                u->data.F32[i] = 0.0;
+            }
+        }
+
+        // 5: Move Q only in the direction u, and minimize the function.
+        psTrace(".psLib.dataManip.psMinimizePowell", 6, "HERE 01\n");
+        for (i=0;i<numDims;i++) {
+            psTrace(".psLib.dataManip.psMinimizePowell", 6,
+                    "u[i] is %f\n", u->data.F32[i]);
+        }
+
+        mul = p_psLineMin(min, params, u, myParamMask, coords, func);
+
+        // 6:
+        if (min->value > currFuncVal) {
+            for (i=0;i<numDims;i++) {
+                psFree(v[i]);
+            }
+            psFree(v);
+            psFree(u);
+            psFree(pQP);
+            psFree(Q);
+            if (paramMask == NULL) {
+                psFree(myParamMask);
+            }
+            psTrace(".psLib.dataManip.psMinimizePowell", 4,
+                    "---- psMinimizePowell() end (true) ----\n");
+            return(true);
+        }
+
+        for (i=0;i<numDims;i++) {
+            if (myParamMask->data.U8[i] == 0) {
+                pQP->data.F32[i] = (2 * Q->data.F32[i]) - params->data.F32[i];
+            } else {
+                pQP->data.F32[i] = params->data.F32[i];
+            }
+        }
+        fqp = func(pQP, coords);
+
+        term1 = (baseFuncVal - currFuncVal) - biggestDiff;
+        term1*= term1;
+        term1*= 2.0 * (baseFuncVal - (2.0 * currFuncVal) + fqp);
+        term2 = baseFuncVal - fqp;
+        term2*= term2 * biggestDiff;
+        if (term1 < term2) {
+            for (i=0;i<numDims;i++) {
+                if (myParamMask->data.U8[i] == 0) {
+                    v[biggestIter]->data.F32[i] = u->data.F32[i];
+                }
+            }
+        }
+
+        // 7: Set P to Q
+        for (i=0;i<numDims;i++) {
+            if (myParamMask->data.U8[i] == 0) {
+                params->data.F32[i] = Q->data.F32[i];
+            }
+        }
+
+        // 8: Go to step 3 until the change is less than some tolerance.
+        if (fabs(baseFuncVal - currFuncVal) <= min->tol) {
+            for (i=0;i<numDims;i++) {
+                psFree(v[i]);
+            }
+            psFree(v);
+            psFree(u);
+            psFree(pQP);
+            psFree(Q);
+            psTrace(".psLib.dataManip.psMinimizePowell", 4,
+                    "---- psMinimizePowell() end (true) ----\n");
+            if (paramMask == NULL) {
+                psFree(myParamMask);
+            }
+            return(true);
+        }
+    }
+
+    if (paramMask == NULL) {
+        psFree(myParamMask);
+    }
+    for (i=0;i<numDims;i++) {
+        psFree(v[i]);
+    }
+    psFree(v);
+    psFree(u);
+    psFree(pQP);
+    psFree(Q);
+    psTrace(".psLib.dataManip.psMinimizePowell", 4,
+            "---- psMinimizePowell() end (false) ----\n");
+    return(false);
+}
+
+/******************************************************************************
+This routine is to be used with the psMinimizeChi2Powell() function below.
+and the psMinimizePowell() function above.
+ 
+The basic idea is calculate chi-squared for a set of params/coords/errors.
+This functions uses global variables to receive the function pointer, the
+data values, and the data errors.
+XXX: This is F32 only
+ *****************************************************************************/
+float myPowellChi2Func(const psVector *params,
+                       const psArray *coords)
+{
+    float chi2 = 0.0;
+    float d;
+    int i;
+    psVector *tmp;
+
+    tmp = Chi2PowellFunc(params, coords);
+    for (i=0;i<coords->n;i++) {
+        d = (tmp->data.F32[i] - myValue->data.F32[i]) / myError->data.F32[i];
+        chi2+= d * d;
+    }
+    psFree(tmp);
+    return(chi2);
+}
+
+
+/******************************************************************************
+This routine must minimize the chi-squared match of a set of data points and
+values for a possibly multi-dimensional function.
+ 
+The basic idea is to use the psMinimizePowell() function defined above.  In
+order to do so, we defined above a function myPowellChi2Func() which takes
+the "func" function and returns chi-squared over the params/coords/values.
+We then use that function myPowellChi2Func() in the call to
+psMinimizePowell().
+ *****************************************************************************/
+bool psMinimizeChi2Powell(psMinimization *min,
+                          psVector *params,
+                          const psVector *paramMask,
+                          const psArray *coords,
+                          const psVector *value,
+                          const psVector *error,
+                          psMinimizeChi2PowellFunc func)
+{
+    myValue = (psVector *) value;
+    myError = (psVector *) error;
+    Chi2PowellFunc = func;
+
+    return(psMinimizePowell(min, params, paramMask, coords, myPowellChi2Func));
+}
+
+
Index: /branches/rel3/psLib/src/math/psMinimize.h
===================================================================
--- /branches/rel3/psLib/src/math/psMinimize.h	(revision 2163)
+++ /branches/rel3/psLib/src/math/psMinimize.h	(revision 2163)
@@ -0,0 +1,127 @@
+/** @file  psMinimize.c
+ *  \brief basic minimization functions
+ *  @ingroup Math
+ *
+ *  This file will contain function prototypes for various minimization,
+ *  chi-squared minimization, and 1-D polynomial fitting routines.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.29 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-06 23:38:49 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#if !defined(PS_MINIMIZE_H)
+#define PS_MINIMIZE_H
+
+#include <stdio.h>
+#include <float.h>
+#include <math.h>
+
+#include "psMemory.h"
+#include "psVector.h"
+#include "psArray.h"
+#include "psImage.h"
+#include "psMatrix.h"
+#include "psFunctions.h"
+#include "psStats.h"
+#include "psTrace.h"
+#include "psLogMsg.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psConstants.h"
+
+
+/** \file psMinimize.h
+ *  \brief minimization operations
+ *  \ingroup Stats
+ */
+/** \addtogroup Stats
+ *  \{
+ */
+
+typedef struct
+{
+    int maxIter;                       ///< Convergence limit
+    float tol;                         ///< Error Tolerance
+    float value;                       ///< Value of function at minimum
+    int iter;                          ///< Number of iterations required
+    float lastDelta;                   ///< The last difference for the fit
+}
+psMinimization;
+
+psMinimization *psMinimizationAlloc(int maxIter,
+                                    float tol);
+
+/** Derive a polynomial fit.
+ *
+ *  psVectorFitPolynomial1d returns the polynomial that best fits the 
+ *  observations. The input parameters are a polynomial that specifies the 
+ *  fit order, myPoly, which will be altered and returned with the best-fit 
+ *  coefficients; and the observations, x, y and yErr. The independent 
+ *  variable list, x may be NULL, in which case the vector index is used. 
+ *  The dependent variable error, yErr may be null, in which case the solution 
+ *  is determined in the assumption that all data errors are equal. This 
+ *  function must be valid only for types psF32, psF64.
+ *
+ *  @return psPolynomial1D*    polynomial fit
+ */
+psPolynomial1D* psVectorFitPolynomial1D(
+    psPolynomial1D* myPoly,            ///< Polynomial to fit
+    const psVector* restrict x,        ///< Ordinates (or NULL to just use the indices)
+    const psVector* restrict y,        ///< Coordinates
+    const psVector* restrict yErr      ///< Errors in coordinates, or NULL
+);
+
+psSpline1D *psVectorFitSpline1D(psSpline1D *mySpline,              ///< The spline which will be generated.
+                                const psVector* restrict x,        ///< Ordinates (or NULL to just use the indices)
+                                const psVector* restrict y,        ///< Coordinates
+                                const psVector* restrict yErr      ///< Errors in coordinates, or NULL
+                               );
+
+
+// XXX: What if any of these arguments are NULL?
+typedef
+float (*psMinimizeLMChi2Func)(psVector *deriv,
+                              const psVector *params,
+                              const psVector *coords);
+
+bool psMinimizeLMChi2(psMinimization *min,
+                      psVector *params,
+                      const psVector *paramMask,
+                      psImage *covar,
+                      const psArray *coords,
+                      const psVector *value,
+                      psMinimizeLMChi2Func func);
+
+typedef
+float (*psMinimizePowellFunc)(const psVector *params,
+                              const psArray *coords);
+
+bool psMinimizePowell(psMinimization *min,
+                      psVector *params,
+                      const psVector *paramMask,
+                      const psArray *coords,
+                      psMinimizePowellFunc func);
+
+typedef
+psVector *(*psMinimizeChi2PowellFunc)(const psVector *params,
+                                      const psArray *coords);
+
+bool psMinimizeChi2Powell(psMinimization *min,
+                          psVector *params,
+                          const psVector *paramMask,
+                          const psArray *coords,
+                          const psVector *value,
+                          const psVector *error,
+                          psMinimizeChi2PowellFunc func);
+
+
+
+/* \} */// End of MathGroup Functions
+
+#endif
+
Index: /branches/rel3/psLib/src/math/psPolynomial.c
===================================================================
--- /branches/rel3/psLib/src/math/psPolynomial.c	(revision 2163)
+++ /branches/rel3/psLib/src/math/psPolynomial.c	(revision 2163)
@@ -0,0 +1,2111 @@
+/** @file  psFunctions.c
+ *
+ *  @brief Contains basic function allocation, deallocation, and evaluation
+ *         routines.
+ *
+ *  This file will hold the functions for allocated, freeing, and evaluating
+ *  polynomials.  It also contains a Gaussian functions.
+ *
+ *  @version $Revision: 1.52 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 01:44:48 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+/*****************************************************************************/
+/*  INCLUDE FILES                                                            */
+/*****************************************************************************/
+#include <gsl/gsl_rng.h>
+#include <gsl/gsl_randist.h>
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <float.h>
+#include <math.h>
+
+#include "psMemory.h"
+#include "psVector.h"
+#include "psScalar.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psLogMsg.h"
+
+#include "psFunctions.h"
+/*****************************************************************************/
+/* DEFINE STATEMENTS                                                         */
+/*****************************************************************************/
+/*
+ * The following macros take the vector IN as input.  If IN is not of
+ * the correct type, then a new vector OUT is created of the correct
+ * type, and the elements of IN and converted to OUT.
+ *
+ * If vector IN is the correct type, then OUT is simply set to IN.
+ */
+#define PS_CONVERT_VECTOR_F32(IN, OUT) \
+if (IN->type.type != PS_TYPE_F32) { \
+    psLogMsg(__func__, PS_LOG_WARN, \
+             "Input vector has incorrect type (%d).\n", \
+             IN->type); \
+    OUT = psVectorAlloc(IN->n, PS_TYPE_F32); \
+    \
+    if (IN->type.type == PS_TYPE_F64) { \
+        for (int i=0;i<IN->n;i++) { \
+            OUT->data.F32[i] = (float) (IN->data.F64[i]); \
+        } \
+    }\
+    else { \
+        psAbort(__func__, "Wrong type.\n"); \
+    } \
+} else { \
+    OUT = (psVector *) IN; \
+}
+
+#define PS_CONVERT_VECTOR_F64(IN, OUT) \
+if (IN->type.type != PS_TYPE_F64) { \
+    psLogMsg(__func__, PS_LOG_WARN, \
+             "Input vector has incorrect type (%d).\n", \
+             IN->type); \
+    OUT = psVectorAlloc(IN->n, PS_TYPE_F64); \
+    \
+    if (IN->type.type == PS_TYPE_F32) { \
+        for (int i=0;i<IN->n;i++) { \
+            OUT->data.F64[i] = (float) (IN->data.F32[i]); \
+        } \
+    }\
+    else { \
+        psAbort(__func__, "Wrong type.\n"); \
+    } \
+} else { \
+    OUT = (psVector *) IN; \
+}
+
+/*****************************************************************************/
+/* TYPE DEFINITIONS                                                          */
+/*****************************************************************************/
+static void polynomial1DFree(psPolynomial1D* myPoly);
+static void polynomial2DFree(psPolynomial2D* myPoly);
+static void polynomial3DFree(psPolynomial3D* myPoly);
+static void polynomial4DFree(psPolynomial4D* myPoly);
+static void dPolynomial1DFree(psDPolynomial1D* myPoly);
+static void dPolynomial2DFree(psDPolynomial2D* myPoly);
+static void dPolynomial3DFree(psDPolynomial3D* myPoly);
+static void dPolynomial4DFree(psDPolynomial4D* myPoly);
+
+/*****************************************************************************/
+/* GLOBAL VARIABLES                                                          */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FILE STATIC VARIABLES                                                     */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - LOCAL                                           */
+/*****************************************************************************/
+
+/*****************************************************************************
+CreateChebyshevPolys(n): this routine takes as input the required order n,
+and returns as output as a pointer to an array of n psPolynomial1D
+structures, corresponding to the first n Chebyshev polynomials.
+ 
+XXX: The output should be static since the Chebyshev polynomials might be
+used frequently and the data structure created here does not contain the
+outer coefficients of the Chebyshev polynomials.
+ *****************************************************************************/
+static psPolynomial1D **CreateChebyshevPolys(int maxChebyPoly)
+{
+    psPolynomial1D **chebPolys = NULL;
+    int i = 0;
+    int j = 0;
+
+    chebPolys = (psPolynomial1D **) psAlloc(maxChebyPoly * sizeof(psPolynomial1D *));
+    for (i = 0; i < maxChebyPoly; i++) {
+        chebPolys[i] = psPolynomial1DAlloc(i + 1, PS_POLYNOMIAL_ORD);
+    }
+
+    // Create the Chebyshev polynomials.
+    // Polynomial i has i-th order.
+    chebPolys[0]->coeff[0] = 1;
+    chebPolys[1]->coeff[1] = 1;
+    for (i = 2; i < maxChebyPoly; i++) {
+        for (j = 0; j < chebPolys[i - 1]->n; j++) {
+            chebPolys[i]->coeff[j + 1] = 2 * chebPolys[i - 1]->coeff[j];
+        }
+        for (j = 0; j < chebPolys[i - 2]->n; j++) {
+            chebPolys[i]->coeff[j] -= chebPolys[i - 2]->coeff[j];
+        }
+    }
+
+    return (chebPolys);
+}
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - PUBLIC                                         */
+/*****************************************************************************/
+
+/*****************************************************************************
+    Evaluate a non-normalized Gaussian with the given mean and sigma at the
+    given coordianate.  Note that this is not a Gaussian deviate.  The
+    evaluated Gaussian is: \f[ exp(-\frac{(x-mean)^2}{2\sigma^2}) \f]
+ *****************************************************************************/
+float psGaussian(float x, float mean, float sigma, bool normal)
+{
+    float tmp = 1.0;
+
+    psTrace(".psLib.dataManip.psFunctions.psGaussian", 4,
+            "---- psGaussian() begin ----\n");
+
+    if (normal == true) {
+        #ifdef DARWIN
+        tmp = 1.0 / (float)sqrt(2.0 * M_PI * (sigma * sigma));
+        #else
+
+        tmp = 1.0 / sqrtf(2.0 * M_PI * (sigma * sigma));
+        #endif
+
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.psGaussian", 4,
+            "---- psGaussian() end ----\n");
+    return(tmp * exp(-((x - mean) * (x - mean)) / (2.0 * sigma * sigma)));
+}
+
+/*****************************************************************************
+    psGaussianDev()
+ This routine creates a psVector of the specified size and type F32
+ and fills it with a random Gaussian distribution of numbers with
+ the specified mean and sigma.  This routine makes use of the GSL
+ routines for generating both uniformly distributed numbers and the
+ Gaussian distribution as well.
+ 
+ NOTE: XXX: There is no way to seed the random generator.
+ *****************************************************************************/
+psVector* psGaussianDev(float mean, float sigma, int Npts)
+{
+    psVector* gauss = NULL;
+    const gsl_rng_type *T = NULL;
+    gsl_rng *r = NULL;
+    int i = 0;
+
+    gauss = psVectorAlloc(Npts, PS_TYPE_F32);
+    gauss->n = Npts;
+    gsl_rng_env_setup();
+    T = gsl_rng_default;
+    r = gsl_rng_alloc(T);
+
+    for (i = 0; i < Npts; i++) {
+        gauss->data.F32[i] = mean + gsl_ran_gaussian(r, sigma);
+    }
+
+    // NOTE: Should I free r as well?
+    return(gauss);
+}
+
+/*****************************************************************************
+    This routine must allocate memory for the polynomial structures.
+ *****************************************************************************/
+psPolynomial1D* psPolynomial1DAlloc(int n,
+                                    psPolynomialType type)
+{
+    int i = 0;
+    psPolynomial1D* newPoly = NULL;
+
+    newPoly = (psPolynomial1D* ) psAlloc(sizeof(psPolynomial1D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) polynomial1DFree);
+
+    newPoly->type = type;
+    newPoly->n = n;
+    newPoly->coeff = (float *)psAlloc(n * sizeof(float));
+    newPoly->coeffErr = (float *)psAlloc(n * sizeof(float));
+    newPoly->mask = (char *)psAlloc(n * sizeof(char));
+    for (i = 0; i < n; i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0;
+    }
+
+    return(newPoly);
+}
+
+psPolynomial2D* psPolynomial2DAlloc(int nX, int nY,
+                                    psPolynomialType type)
+{
+    int x = 0;
+    int y = 0;
+    psPolynomial2D* newPoly = NULL;
+
+    newPoly = (psPolynomial2D* ) psAlloc(sizeof(psPolynomial2D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) polynomial2DFree);
+
+    newPoly->type = type;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+
+    newPoly->coeff = (float **)psAlloc(nX * sizeof(float *));
+    newPoly->coeffErr = (float **)psAlloc(nX * sizeof(float *));
+    newPoly->mask = (char **)psAlloc(nX * sizeof(char *));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (float *)psAlloc(nY * sizeof(float));
+        newPoly->coeffErr[x] = (float *)psAlloc(nY * sizeof(float));
+        newPoly->mask[x] = (char *)psAlloc(nY * sizeof(char));
+    }
+    for (x = 0; x < nX; x++) {
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = 0.0;
+            newPoly->coeffErr[x][y] = 0.0;
+            newPoly->mask[x][y] = 0;
+        }
+    }
+
+    return(newPoly);
+}
+
+psPolynomial3D* psPolynomial3DAlloc(int nX, int nY, int nZ,
+                                    psPolynomialType type)
+{
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psPolynomial3D* newPoly = NULL;
+
+    newPoly = (psPolynomial3D* ) psAlloc(sizeof(psPolynomial3D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) polynomial3DFree);
+
+    newPoly->type = type;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff = (float ***)psAlloc(nX * sizeof(float **));
+    newPoly->coeffErr = (float ***)psAlloc(nX * sizeof(float **));
+    newPoly->mask = (char ***)psAlloc(nX * sizeof(char **));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (float **)psAlloc(nY * sizeof(float *));
+        newPoly->coeffErr[x] = (float **)psAlloc(nY * sizeof(float *));
+        newPoly->mask[x] = (char **)psAlloc(nY * sizeof(char *));
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = (float *)psAlloc(nZ * sizeof(float));
+            newPoly->coeffErr[x][y] = (float *)psAlloc(nZ * sizeof(float));
+            newPoly->mask[x][y] = (char *)psAlloc(nZ * sizeof(char));
+        }
+    }
+    for (x = 0; x < nX; x++) {
+        for (y = 0; y < nY; y++) {
+            for (z = 0; z < nZ; z++) {
+                newPoly->coeff[x][y][z] = 0.0;
+                newPoly->coeffErr[x][y][z] = 0.0;
+                newPoly->mask[x][y][z] = 0;
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+psPolynomial4D* psPolynomial4DAlloc(int nW, int nX, int nY, int nZ,
+                                    psPolynomialType type)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psPolynomial4D* newPoly = NULL;
+
+    newPoly = (psPolynomial4D* ) psAlloc(sizeof(psPolynomial4D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) polynomial4DFree);
+
+    newPoly->type = type;
+    newPoly->nW = nW;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff = (float ****)psAlloc(nW * sizeof(float ***));
+    newPoly->coeffErr = (float ****)psAlloc(nW * sizeof(float ***));
+    newPoly->mask = (char ****)psAlloc(nW * sizeof(char ***));
+    for (w = 0; w < nW; w++) {
+        newPoly->coeff[w] = (float ***)psAlloc(nX * sizeof(float **));
+        newPoly->coeffErr[w] = (float ***)psAlloc(nX * sizeof(float **));
+        newPoly->mask[w] = (char ***)psAlloc(nX * sizeof(char **));
+        for (x = 0; x < nX; x++) {
+            newPoly->coeff[w][x] = (float **)psAlloc(nY * sizeof(float *));
+            newPoly->coeffErr[w][x] = (float **)psAlloc(nY * sizeof(float *));
+            newPoly->mask[w][x] = (char **)psAlloc(nY * sizeof(char *));
+            for (y = 0; y < nY; y++) {
+                newPoly->coeff[w][x][y] = (float *)psAlloc(nZ * sizeof(float));
+                newPoly->coeffErr[w][x][y] = (float *)psAlloc(nZ * sizeof(float));
+                newPoly->mask[w][x][y] = (char *)psAlloc(nZ * sizeof(char));
+            }
+        }
+    }
+    for (w = 0; w < nW; w++) {
+        for (x = 0; x < nX; x++) {
+            for (y = 0; y < nY; y++) {
+                for (z = 0; z < nZ; z++) {
+                    newPoly->coeff[w][x][y][z] = 0.0;
+                    newPoly->coeffErr[w][x][y][z] = 0.0;
+                    newPoly->mask[w][x][y][z] = 0;
+                }
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+static void polynomial1DFree(psPolynomial1D* myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void polynomial2DFree(psPolynomial2D* myPoly)
+{
+    int x = 0;
+
+    for (x = 0; x < myPoly->nX; x++) {
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void polynomial3DFree(psPolynomial3D* myPoly)
+{
+    int x = 0;
+    int y = 0;
+
+    for (x = 0; x < myPoly->nX; x++) {
+        for (y = 0; y < myPoly->nY; y++) {
+            psFree(myPoly->coeff[x][y]);
+            psFree(myPoly->coeffErr[x][y]);
+            psFree(myPoly->mask[x][y]);
+        }
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void polynomial4DFree(psPolynomial4D* myPoly)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+
+    for (w = 0; w < myPoly->nW; w++) {
+        for (x = 0; x < myPoly->nX; x++) {
+            for (y = 0; y < myPoly->nY; y++) {
+                psFree(myPoly->coeff[w][x][y]);
+                psFree(myPoly->coeffErr[w][x][y]);
+                psFree(myPoly->mask[w][x][y]);
+            }
+            psFree(myPoly->coeff[w][x]);
+            psFree(myPoly->coeffErr[w][x]);
+            psFree(myPoly->mask[w][x]);
+        }
+        psFree(myPoly->coeff[w]);
+        psFree(myPoly->coeffErr[w]);
+        psFree(myPoly->mask[w]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ 
+    XXX: Should the "coeffErr[]" should be used as well?
+ *****************************************************************************/
+float p_psOrdPolynomial1DEval(float x, const psPolynomial1D* myPoly)
+{
+    int loop_x = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+
+    psTrace(".psLib.dataManip.psFunctions.p_psOrdPolynomial1DEval", 4,
+            "---- Calling p_psOrdPolynomial1DEval(%f)\n", x);
+    psTrace(".psLib.dataManip.psFunctions.p_psOrdPolynomial1DEval", 4,
+            "Polynomial order is %d\n", myPoly->n);
+    for (loop_x = 0; loop_x < myPoly->n; loop_x++) {
+        psTrace(".psLib.dataManip.psFunctions.p_psOrdPolynomial1DEval", 4,
+                "Polynomial coeff[%d] is %f\n", loop_x, myPoly->coeff[loop_x]);
+    }
+
+
+    if (NULL == myPoly) {
+        psAbort(__func__, "psPolynomial1DEval(): myPoly is NULL\n");
+    }
+
+    // NOTE: Do we want to flag this case?
+    if (myPoly->n == 0) {
+        return(1.0);
+    }
+
+    if (NULL == myPoly->coeff) {
+        psAbort(__func__, "psPolynomial1DEval(): myPoly->coeff is NULL\n");
+    }
+
+    for (loop_x = 0; loop_x < myPoly->n; loop_x++) {
+        if (myPoly->mask[loop_x] == 0) {
+            psTrace(".psLib.dataManip.psFunctions.p_psOrdPolynomial1DEval", 10,
+                    "polysum+= sum*coeff [%f+= (%f * %f)\n", polySum, xSum, myPoly->coeff[loop_x]);
+            polySum += xSum * myPoly->coeff[loop_x];
+            xSum *= x;
+        }
+    }
+
+    return(polySum);
+}
+
+// XXX: You can do this without having to psAlloc() vector d.
+// XXX: How does the mask vector effect Crenshaw's formula?
+float p_psChebPolynomial1DEval(float x, const psPolynomial1D* myPoly)
+{
+    psVector *d;
+    int n;
+    int i;
+    float tmp;
+
+    n = myPoly->n;
+    d = psVectorAlloc(n, PS_TYPE_F32);
+    d->data.F32[n-1] = myPoly->coeff[n-1];
+    d->data.F32[n-2] = (2.0 * x * d->data.F32[n-1]) + myPoly->coeff[n-2];
+    for (i=n-3;i>=1;i--) {
+        d->data.F32[i] = (2.0 * x * d->data.F32[i+1]) -
+                         (d->data.F32[i+2]) +
+                         (myPoly->coeff[i]);
+    }
+
+    tmp = (x * d->data.F32[1]) -
+          (d->data.F32[2]) +
+          (0.5 * myPoly->coeff[0]);
+
+    psFree(d);
+    return(tmp);
+    /*
+
+    int n;
+    int i;
+    float tmp;
+    psPolynomial1D **chebPolys = NULL;
+
+    n = myPoly->n;
+    chebPolys = CreateChebyshevPolys(n);
+
+    tmp = 0.0;
+    for (i=0;i<myPoly->n;i++) {
+        tmp+= (myPoly->coeff[i] * psPolynomial1DEval(x, chebPolys[i]));
+        //            printf("HMMM: psPolynomial1DEval(%f, chebPolys[%d]) is %f\n", x, i, psPolynomial1DEval(x, chebPolys[i]));
+    }
+    tmp-= (myPoly->coeff[0]/2.0);
+
+
+    return(tmp);
+    */
+}
+
+float psPolynomial1DEval(float x, const psPolynomial1D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psOrdPolynomial1DEval(x, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psChebPolynomial1DEval(x, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psPolynomial1DEvalVector(const psVector *x,
+                                   const psPolynomial1D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    int i;
+
+    PS_CONVERT_VECTOR_F32(x, myX);
+
+    tmp = psVectorAlloc(x->n, PS_TYPE_F32);
+    for (i=0;i<x->n;i++) {
+        tmp->data.F32[i] = psPolynomial1DEval(x->data.F32[i], myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    return(tmp);
+}
+
+
+float p_psOrdPolynomial2DEval(float x, float y, const psPolynomial2D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        ySum = xSum;
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            if (myPoly->mask[loop_x][loop_y] == 0) {
+                polySum += ySum * myPoly->coeff[loop_x][loop_y];
+                ySum *= y;
+            }
+        }
+        xSum *= x;
+    }
+
+    return(polySum);
+}
+
+float p_psChebPolynomial2DEval(float x, float y, const psPolynomial2D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int i = 0;
+    float polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nX;
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            if (myPoly->mask[loop_x][loop_y] == 0) {
+                polySum += myPoly->coeff[loop_x][loop_y] *
+                           psPolynomial1DEval(x, chebPolys[loop_x]) *
+                           psPolynomial1DEval(y, chebPolys[loop_y]);
+            }
+        }
+    }
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+float psPolynomial2DEval(float x, float y, const psPolynomial2D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psOrdPolynomial2DEval(x, y, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psChebPolynomial2DEval(x, y, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+
+psVector *psPolynomial2DEvalVector(const psVector *x,
+                                   const psVector *y,
+                                   const psPolynomial2D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F32(x, myX);
+    PS_CONVERT_VECTOR_F32(y, myY);
+    vecLen=x->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F32);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F32[i] = psPolynomial2DEval(myX->data.F32[i],
+                                              myY->data.F32[i],
+                                              myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F32) {
+        psFree(myY);
+    }
+    return(tmp);
+}
+
+
+
+float p_psOrdPolynomial3DEval(float x, float y, float z, const psPolynomial3D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+    float zSum = 1.0;
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        ySum = xSum;
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            zSum = ySum;
+            for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                if (myPoly->mask[loop_x][loop_y][loop_z] == 0) {
+                    polySum += zSum * myPoly->coeff[loop_x][loop_y][loop_z];
+                    zSum *= z;
+                }
+            }
+            ySum *= y;
+        }
+        xSum *= x;
+    }
+
+    return(polySum);
+}
+
+float p_psChebPolynomial3DEval(float x, float y, float z, const psPolynomial3D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    int i = 0;
+    float polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nX;
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    if (myPoly->nZ > maxChebyPoly) {
+        maxChebyPoly = myPoly->nZ;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                if (myPoly->mask[loop_x][loop_y][loop_z] == 0) {
+                    polySum += myPoly->coeff[loop_x][loop_y][loop_z] *
+                               psPolynomial1DEval(x, chebPolys[loop_x]) *
+                               psPolynomial1DEval(y, chebPolys[loop_y]) *
+                               psPolynomial1DEval(z, chebPolys[loop_z]);
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+float psPolynomial3DEval(float x, float y, float z, const psPolynomial3D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psOrdPolynomial3DEval(x, y, z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psChebPolynomial3DEval(x, y, z, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psPolynomial3DEvalVector(const psVector *x,
+                                   const psVector *y,
+                                   const psVector *z,
+                                   const psPolynomial3D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F32(x, myX);
+    PS_CONVERT_VECTOR_F32(y, myY);
+    PS_CONVERT_VECTOR_F32(z, myZ);
+    vecLen=x->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+    if (z->n < vecLen) {
+        vecLen = z->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F32);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F32[i] = psPolynomial3DEval(myX->data.F32[i],
+                                              myY->data.F32[i],
+                                              myZ->data.F32[i],
+                                              myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F32) {
+        psFree(myY);
+    }
+    if (z->type.type != PS_TYPE_F32) {
+        psFree(myZ);
+    }
+    return(tmp);
+}
+
+
+
+
+
+
+float p_psOrdPolynomial4DEval(float w, float x, float y, float z, const psPolynomial4D* myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    float polySum = 0.0;
+    float wSum = 1.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+    float zSum = 1.0;
+
+    for (loop_w = 0; loop_w < myPoly->nW; loop_w++) {
+        xSum = wSum;
+        for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+            ySum = xSum;
+            for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+                zSum = ySum;
+                for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                    if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) {
+                        polySum += zSum * myPoly->coeff[loop_w][loop_x][loop_y][loop_z];
+                        zSum *= z;
+                    }
+                }
+                ySum *= y;
+            }
+            xSum *= x;
+        }
+        wSum *= w;
+    }
+
+    return(polySum);
+}
+
+float p_psChebPolynomial4DEval(float w, float x, float y, float z, const psPolynomial4D* myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    int i = 0;
+    float polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nW;
+    if (myPoly->nX > maxChebyPoly) {
+        maxChebyPoly = myPoly->nX;
+    }
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    if (myPoly->nZ > maxChebyPoly) {
+        maxChebyPoly = myPoly->nZ;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_w = 0; loop_w < myPoly->nW; loop_w++) {
+        for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+            for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+                for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                    if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) {
+                        polySum += myPoly->coeff[loop_w][loop_x][loop_y][loop_z] *
+                                   psPolynomial1DEval(w, chebPolys[loop_w]) *
+                                   psPolynomial1DEval(x, chebPolys[loop_x]) *
+                                   psPolynomial1DEval(y, chebPolys[loop_y]) *
+                                   psPolynomial1DEval(z, chebPolys[loop_z]);
+                    }
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+float psPolynomial4DEval(float w, float x, float y, float z, const psPolynomial4D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psOrdPolynomial4DEval(w,x,y,z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psChebPolynomial4DEval(w,x,y,z, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psPolynomial4DEvalVector(const psVector *w,
+                                   const psVector *x,
+                                   const psVector *y,
+                                   const psVector *z,
+                                   const psPolynomial4D *myPoly)
+{
+    psVector *tmp;
+    psVector *myW;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F32(w, myW);
+    PS_CONVERT_VECTOR_F32(x, myX);
+    PS_CONVERT_VECTOR_F32(y, myY);
+    PS_CONVERT_VECTOR_F32(z, myZ);
+    vecLen=w->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+    if (x->n < vecLen) {
+        vecLen = x->n;
+    }
+    if (z->n < vecLen) {
+        vecLen = z->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F32);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F32[i] = psPolynomial4DEval(myW->data.F32[i],
+                                              myX->data.F32[i],
+                                              myY->data.F32[i],
+                                              myZ->data.F32[i],
+                                              myPoly);
+    }
+
+    if (w->type.type != PS_TYPE_F32) {
+        psFree(myW);
+    }
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F32) {
+        psFree(myY);
+    }
+    if (z->type.type != PS_TYPE_F32) {
+        psFree(myZ);
+    }
+    return(tmp);
+}
+
+
+
+
+
+psDPolynomial1D* psDPolynomial1DAlloc(int n,
+                                      psPolynomialType type)
+{
+    int i = 0;
+    psDPolynomial1D* newPoly = NULL;
+
+    newPoly = (psDPolynomial1D* ) psAlloc(sizeof(psDPolynomial1D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) dPolynomial1DFree);
+
+    newPoly->type = type;
+    newPoly->n = n;
+    newPoly->coeff = (double *)psAlloc(n * sizeof(double));
+    newPoly->coeffErr = (double *)psAlloc(n * sizeof(double));
+    newPoly->mask = (char *)psAlloc(n * sizeof(char));
+    for (i = 0; i < n; i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0;
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial2D* psDPolynomial2DAlloc(int nX, int nY,
+                                      psPolynomialType type)
+{
+    int x = 0;
+    int y = 0;
+    psDPolynomial2D* newPoly = NULL;
+
+    newPoly = (psDPolynomial2D* ) psAlloc(sizeof(psDPolynomial2D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) dPolynomial2DFree);
+
+    newPoly->type = type;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+
+    newPoly->coeff = (double **)psAlloc(nX * sizeof(double *));
+    newPoly->coeffErr = (double **)psAlloc(nX * sizeof(double *));
+    newPoly->mask = (char **)psAlloc(nX * sizeof(char *));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (double *)psAlloc(nY * sizeof(double));
+        newPoly->coeffErr[x] = (double *)psAlloc(nY * sizeof(double));
+        newPoly->mask[x] = (char *)psAlloc(nY * sizeof(char));
+    }
+    for (x = 0; x < nX; x++) {
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = 0.0;
+            newPoly->coeffErr[x][y] = 0.0;
+            newPoly->mask[x][y] = 0;
+        }
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial3D* psDPolynomial3DAlloc(int nX, int nY, int nZ,
+                                      psPolynomialType type)
+{
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psDPolynomial3D* newPoly = NULL;
+
+    newPoly = (psDPolynomial3D* ) psAlloc(sizeof(psDPolynomial3D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) dPolynomial3DFree);
+
+    newPoly->type = type;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff = (double ***)psAlloc(nX * sizeof(double **));
+    newPoly->coeffErr = (double ***)psAlloc(nX * sizeof(double **));
+    newPoly->mask = (char ***)psAlloc(nX * sizeof(char **));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (double **)psAlloc(nY * sizeof(double *));
+        newPoly->coeffErr[x] = (double **)psAlloc(nY * sizeof(double *));
+        newPoly->mask[x] = (char **)psAlloc(nY * sizeof(char *));
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = (double *)psAlloc(nZ * sizeof(double));
+            newPoly->coeffErr[x][y] = (double *)psAlloc(nZ * sizeof(double));
+            newPoly->mask[x][y] = (char *)psAlloc(nZ * sizeof(char));
+        }
+    }
+    for (x = 0; x < nX; x++) {
+        for (y = 0; y < nY; y++) {
+            for (z = 0; z < nZ; z++) {
+                newPoly->coeff[x][y][z] = 0.0;
+                newPoly->coeffErr[x][y][z] = 0.0;
+                newPoly->mask[x][y][z] = 0;
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial4D* psDPolynomial4DAlloc(int nW, int nX, int nY, int nZ,
+                                      psPolynomialType type)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psDPolynomial4D* newPoly = NULL;
+
+    newPoly = (psDPolynomial4D* ) psAlloc(sizeof(psDPolynomial4D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) dPolynomial4DFree);
+
+    newPoly->type = type;
+    newPoly->nW = nW;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff = (double ****)psAlloc(nW * sizeof(double ***));
+    newPoly->coeffErr = (double ****)psAlloc(nW * sizeof(double ***));
+    newPoly->mask = (char ****)psAlloc(nW * sizeof(char ***));
+    for (w = 0; w < nW; w++) {
+        newPoly->coeff[w] = (double ***)psAlloc(nX * sizeof(double **));
+        newPoly->coeffErr[w] = (double ***)psAlloc(nX * sizeof(double **));
+        newPoly->mask[w] = (char ***)psAlloc(nX * sizeof(char **));
+        for (x = 0; x < nX; x++) {
+            newPoly->coeff[w][x] = (double **)psAlloc(nY * sizeof(double *));
+            newPoly->coeffErr[w][x] = (double **)psAlloc(nY * sizeof(double *));
+            newPoly->mask[w][x] = (char **)psAlloc(nY * sizeof(char *));
+            for (y = 0; y < nY; y++) {
+                newPoly->coeff[w][x][y] = (double *)psAlloc(nZ * sizeof(double));
+                newPoly->coeffErr[w][x][y] = (double *)psAlloc(nZ * sizeof(double));
+                newPoly->mask[w][x][y] = (char *)psAlloc(nZ * sizeof(char));
+            }
+        }
+    }
+    for (w = 0; w < nW; w++) {
+        for (x = 0; x < nX; x++) {
+            for (y = 0; y < nY; y++) {
+                for (z = 0; z < nZ; z++) {
+                    newPoly->coeff[w][x][y][z] = 0.0;
+                    newPoly->coeffErr[w][x][y][z] = 0.0;
+                    newPoly->mask[w][x][y][z] = 0;
+                }
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+static void dPolynomial1DFree(psDPolynomial1D* myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void dPolynomial2DFree(psDPolynomial2D* myPoly)
+{
+    int x = 0;
+
+    for (x = 0; x < myPoly->nX; x++) {
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void dPolynomial3DFree(psDPolynomial3D* myPoly)
+{
+    int x = 0;
+    int y = 0;
+
+    for (x = 0; x < myPoly->nX; x++) {
+        for (y = 0; y < myPoly->nY; y++) {
+            psFree(myPoly->coeff[x][y]);
+            psFree(myPoly->coeffErr[x][y]);
+            psFree(myPoly->mask[x][y]);
+        }
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void dPolynomial4DFree(psDPolynomial4D* myPoly)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+
+    for (w = 0; w < myPoly->nW; w++) {
+        for (x = 0; x < myPoly->nX; x++) {
+            for (y = 0; y < myPoly->nY; y++) {
+                psFree(myPoly->coeff[w][x][y]);
+                psFree(myPoly->coeffErr[w][x][y]);
+                psFree(myPoly->mask[w][x][y]);
+            }
+            psFree(myPoly->coeff[w][x]);
+            psFree(myPoly->coeffErr[w][x]);
+            psFree(myPoly->mask[w][x]);
+        }
+        psFree(myPoly->coeff[w]);
+        psFree(myPoly->coeffErr[w]);
+        psFree(myPoly->mask[w]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ *****************************************************************************/
+double p_psDOrdPolynomial1DEval(double x, const psDPolynomial1D* myPoly)
+{
+    int loop_x = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+
+    // NOTE: Do we want to flag this case?
+    if (myPoly->n == 0) {
+        return(1.0);
+    }
+
+    for (loop_x = 0; loop_x < myPoly->n; loop_x++) {
+        if (myPoly->mask[loop_x] == 0) {
+            polySum += xSum * myPoly->coeff[loop_x];
+            xSum *= x;
+        }
+    }
+
+    return(polySum);
+}
+
+// XXX: You can do this without having to psAlloc() vector d.
+// XXX: How does the mask vector effect Crenshaw's formula?
+double p_psDChebPolynomial1DEval(double x, const psDPolynomial1D* myPoly)
+{
+    psVector *d;
+    int n;
+    int i;
+    double tmp;
+
+    n = myPoly->n;
+    d = psVectorAlloc(n, PS_TYPE_F64);
+    d->data.F64[n-1] = myPoly->coeff[n-1];
+    d->data.F64[n-2] = (2.0 * x * d->data.F64[n-1]) + myPoly->coeff[n-2];
+    for (i=n-3;i>=1;i--) {
+        d->data.F64[i] = (2.0 * x * d->data.F64[i+1]) -
+                         (d->data.F64[i+2]) +
+                         (myPoly->coeff[i]);
+    }
+
+    tmp = (x * d->data.F64[1]) -
+          (d->data.F64[2]) +
+          (0.5 * myPoly->coeff[0]);
+
+    psFree(d);
+    return(tmp);
+}
+
+double psDPolynomial1DEval(double x, const psDPolynomial1D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psDOrdPolynomial1DEval(x, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psDChebPolynomial1DEval(x, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psDPolynomial1DEvalVector(const psVector *x,
+                                    const psDPolynomial1D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    int i;
+
+    PS_CONVERT_VECTOR_F64(x, myX);
+
+    tmp = psVectorAlloc(x->n, PS_TYPE_F64);
+    for (i=0;i<x->n;i++) {
+        tmp->data.F64[i] = psDPolynomial1DEval(x->data.F64[i], myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    return(tmp);
+}
+
+
+
+double p_psDOrdPolynomial2DEval(double x, double y, const psDPolynomial2D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        ySum = xSum;
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            if (myPoly->mask[loop_x][loop_y] == 0) {
+                polySum += ySum * myPoly->coeff[loop_x][loop_y];
+                ySum *= y;
+            }
+        }
+        xSum *= x;
+    }
+
+    return(polySum);
+}
+
+double p_psDChebPolynomial2DEval(double x, double y, const psDPolynomial2D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int i = 0;
+    double polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nX;
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            if (myPoly->mask[loop_x][loop_y] == 0) {
+                polySum += myPoly->coeff[loop_x][loop_y] *
+                           psPolynomial1DEval(x, chebPolys[loop_x]) *
+                           psPolynomial1DEval(y, chebPolys[loop_y]);
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+double psDPolynomial2DEval(double x, double y, const psDPolynomial2D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psDOrdPolynomial2DEval(x, y, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psDChebPolynomial2DEval(x, y, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psDPolynomial2DEvalVector(const psVector *x,
+                                    const psVector *y,
+                                    const psDPolynomial2D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F64(x, myX);
+    PS_CONVERT_VECTOR_F64(y, myY);
+    vecLen=x->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F64);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F64[i] = psDPolynomial2DEval(myX->data.F64[i],
+                                               myY->data.F64[i],
+                                               myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F64) {
+        psFree(myY);
+    }
+    return(tmp);
+}
+
+
+
+double p_psDOrdPolynomial3DEval(double x, double y, double z, const psDPolynomial3D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+    double zSum = 1.0;
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        ySum = xSum;
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            zSum = ySum;
+            for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                if (myPoly->mask[loop_x][loop_y][loop_z] == 0) {
+                    polySum += zSum * myPoly->coeff[loop_x][loop_y][loop_z];
+                    zSum *= z;
+                }
+            }
+            ySum *= y;
+        }
+        xSum *= x;
+    }
+
+    return(polySum);
+}
+
+double p_psDChebPolynomial3DEval(double x, double y, double z, const psDPolynomial3D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    int i = 0;
+    double polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nX;
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    if (myPoly->nZ > maxChebyPoly) {
+        maxChebyPoly = myPoly->nZ;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                if (myPoly->mask[loop_x][loop_y][loop_z] == 0) {
+                    polySum += myPoly->coeff[loop_x][loop_y][loop_z] *
+                               psPolynomial1DEval(x, chebPolys[loop_x]) *
+                               psPolynomial1DEval(y, chebPolys[loop_y]) *
+                               psPolynomial1DEval(z, chebPolys[loop_z]);
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+double psDPolynomial3DEval(double x, double y, double z, const psDPolynomial3D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psDOrdPolynomial3DEval(x, y, z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psDChebPolynomial3DEval(x, y, z, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psDPolynomial3DEvalVector(const psVector *x,
+                                    const psVector *y,
+                                    const psVector *z,
+                                    const psDPolynomial3D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F64(x, myX);
+    PS_CONVERT_VECTOR_F64(y, myY);
+    PS_CONVERT_VECTOR_F64(z, myZ);
+    vecLen=x->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+    if (z->n < vecLen) {
+        vecLen = z->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F64);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F64[i] = psDPolynomial3DEval(myX->data.F64[i],
+                                               myY->data.F64[i],
+                                               myZ->data.F64[i],
+                                               myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F64) {
+        psFree(myY);
+    }
+    if (z->type.type != PS_TYPE_F64) {
+        psFree(myZ);
+    }
+    return(tmp);
+}
+
+
+
+
+
+
+
+
+double p_psDOrdPolynomial4DEval(double w, double x, double y, double z, const psDPolynomial4D* myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    double polySum = 0.0;
+    double wSum = 1.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+    double zSum = 1.0;
+
+    for (loop_w = 0; loop_w < myPoly->nW; loop_w++) {
+        xSum = wSum;
+        for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+            ySum = xSum;
+            for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+                zSum = ySum;
+                for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                    if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) {
+                        polySum += zSum * myPoly->coeff[loop_w][loop_x][loop_y][loop_z];
+                        zSum *= z;
+                    }
+                }
+                ySum *= y;
+            }
+            xSum *= x;
+        }
+        wSum *= w;
+    }
+
+    return(polySum);
+}
+
+double p_psDChebPolynomial4DEval(double w, double x, double y, double z, const psDPolynomial4D* myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    int i = 0;
+    double polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nW;
+    if (myPoly->nX > maxChebyPoly) {
+        maxChebyPoly = myPoly->nX;
+    }
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    if (myPoly->nZ > maxChebyPoly) {
+        maxChebyPoly = myPoly->nZ;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_w = 0; loop_w < myPoly->nW; loop_w++) {
+        for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+            for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+                for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                    if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) {
+                        polySum += myPoly->coeff[loop_w][loop_x][loop_y][loop_z] *
+                                   psPolynomial1DEval(w, chebPolys[loop_w]) *
+                                   psPolynomial1DEval(x, chebPolys[loop_x]) *
+                                   psPolynomial1DEval(y, chebPolys[loop_y]) *
+                                   psPolynomial1DEval(z, chebPolys[loop_z]);
+                    }
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+double psDPolynomial4DEval(double w, double x, double y, double z, const psDPolynomial4D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psDOrdPolynomial4DEval(w,x,y,z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psDChebPolynomial4DEval(w,x,y,z, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psDPolynomial4DEvalVector(const psVector *w,
+                                    const psVector *x,
+                                    const psVector *y,
+                                    const psVector *z,
+                                    const psDPolynomial4D *myPoly)
+{
+    psVector *tmp;
+    psVector *myW;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F64(w, myW);
+    PS_CONVERT_VECTOR_F64(x, myX);
+    PS_CONVERT_VECTOR_F64(y, myY);
+    PS_CONVERT_VECTOR_F64(z, myZ);
+    vecLen=w->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+    if (x->n < vecLen) {
+        vecLen = x->n;
+    }
+    if (z->n < vecLen) {
+        vecLen = z->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F64);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F64[i] = psDPolynomial4DEval(myW->data.F64[i],
+                                               myX->data.F64[i],
+                                               myY->data.F64[i],
+                                               myZ->data.F64[i],
+                                               myPoly);
+    }
+
+    if (w->type.type != PS_TYPE_F64) {
+        psFree(myW);
+    }
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F64) {
+        psFree(myY);
+    }
+    if (z->type.type != PS_TYPE_F64) {
+        psFree(myZ);
+    }
+    return(tmp);
+}
+
+
+
+
+//typedef struct {
+//    int n;
+//    psPolynomial1D **spline;
+//    float *p_psDeriv2;
+//    float *domains;
+//} psSpline1D;
+
+/*****************************************************************************
+    NOTE: "n" specifies the number of spline polynomials.  Therefore, there
+    must exist n+1 points in "domains".
+ 
+XXX: Ensure that domain[i+1] != domain[i]
+ *****************************************************************************/
+psSpline1D *psSpline1DAlloc(int numSplines,
+                            int order,
+                            float min,
+                            float max)
+{
+    psSpline1D *tmp = NULL;
+    int i;
+    float tmpDomain;
+    float width;
+
+    if (fabs(max-min) < FLT_EPSILON) {
+        psLogMsg(__func__, PS_LOG_WARN, "min and max are the same.\n");
+        return(NULL);
+    }
+
+    tmp = (psSpline1D *) psAlloc(sizeof(psSpline1D));
+    tmp->n = numSplines;
+
+    tmp->spline = (psPolynomial1D **) psAlloc(numSplines * sizeof(psPolynomial1D *));
+    for (i=0;i<numSplines;i++) {
+        (tmp->spline)[i] = psPolynomial1DAlloc(order+1, PS_POLYNOMIAL_ORD);
+    }
+
+    // This should be set by the psVectorFitSpline1D()
+    tmp->p_psDeriv2 = NULL;
+
+    tmp->domains = (float *) psAlloc((numSplines+1) * sizeof(float));
+    width = (max - min) / ((float) numSplines);
+
+    (tmp->domains)[0] = min;
+    tmpDomain = min+width;
+    for (i=1;i<numSplines+1;i++) {
+        (tmp->domains)[i] = tmpDomain;
+        tmpDomain+= width;
+    }
+    (tmp->domains)[numSplines] = max;
+
+    return(tmp);
+}
+
+// XXX: Have Robert put the dealocator in the memory file.
+int p_psSpline1DFree(psSpline1D *tmpSpline)
+{
+    int i;
+
+    if (tmpSpline == NULL) {
+        return(0);
+    }
+
+    if (tmpSpline->spline != NULL) {
+        for (i=0;i<tmpSpline->n;i++) {
+            psFree((tmpSpline->spline)[i]);
+        }
+        psFree(tmpSpline->spline);
+    }
+
+    if (tmpSpline->p_psDeriv2 != NULL) {
+        psFree(tmpSpline->p_psDeriv2);
+    }
+    psFree(tmpSpline->domains);
+    psFree(tmpSpline);
+
+    return(0);
+}
+
+/*****************************************************************************
+ *****************************************************************************/
+psSpline1D *psSpline1DAllocGeneric(const psVector *bounds,
+                                   int order)
+{
+    psSpline1D *tmp = NULL;
+    int i;
+    int numSplines;
+
+    tmp = (psSpline1D *) psAlloc(sizeof(psSpline1D));
+
+    numSplines = bounds->n - 1;
+    tmp->n = numSplines;
+
+    tmp->spline = (psPolynomial1D **) psAlloc(numSplines * sizeof(psPolynomial1D *));
+    for (i=0;i<numSplines;i++) {
+        (tmp->spline)[i] = psPolynomial1DAlloc(order+1, PS_POLYNOMIAL_ORD);
+    }
+
+    tmp->domains = (float *) psAlloc((bounds->n) * sizeof(float));
+
+    for (i=0;i<bounds->n;i++) {
+        (tmp->domains)[i] = bounds->data.F32[i];
+        if (i<(bounds->n-1)) {
+            if (FLT_EPSILON < fabs(bounds->data.F32[i+1]-bounds->data.F32[i])) {
+                // XXX: psErrorMsg(data points must be distinct)
+            }
+        }
+    }
+
+    return(tmp);
+}
+
+/*****************************************************************************
+p_psVectorBinDisectF32(): This is a private function which takes as input a
+vector of floating point data as well as a single floating point values.
+The input vector values are assumed to be non-decreasing (v[i-1] <= v[j] for
+all j>=i).  This routine does a binary disection of the vector and returns
+"i" such that (v[i] <= x <= v[i+1).  If x lies outside the range of v[],
+then this routine prints a warning message and returns (-2 or -1).
+ 
+XXX: Macro this for a few different types.
+ 
+XXX: name since we don't take psVectors as input.
+ *****************************************************************************/
+int p_psVectorBinDisectF32(float *bins,
+                           int numBins,
+                           float x)
+{
+    int min;
+    int max;
+    int mid;
+
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectF32", 4,
+            "---- Calling p_psVectorBinDisectF32(%f)\n", x);
+
+    if (x < bins[0]) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "p_psVectorBinDisectF32(): ordinate %f is outside vector range (%f - %f).",
+                 x, bins[0], bins[numBins-1]);
+        return(-2);
+    }
+
+    if (x > bins[numBins-1]) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "p_psVectorBinDisectF32(): ordinate %f is outside vector range (%f - %f).",
+                 x, bins[0], bins[numBins-1]);
+        return(-1);
+    }
+
+    min = 0;
+    max = numBins-2;
+    mid = ((max+1)-min)/2;
+
+    while (min != max) {
+        psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectF32", 4,
+                "(min, mid, max) is (%d, %d, %d): (x, bins) is (%f, %f)\n",
+                min, mid, max, x, bins[mid]);
+
+        if (x == bins[mid]) {
+            psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectF32", 4,
+                    "---- Exiting p_psVectorBinDisectF32(): bin %d\n", mid);
+            return(mid);
+        } else if (x < bins[mid]) {
+            max = mid-1;
+        } else {
+            min = mid;
+        }
+        mid = ((max+1)+min)/2;
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectF32", 4,
+            "---- Exiting p_psVectorBinDisectF32(): bin %d\n", min);
+    return(min);
+}
+
+/*****************************************************************************
+p_psVectorBinDisectS32(): integer version of above.
+ *****************************************************************************/
+int p_psVectorBinDisectS32(int *bins,
+                           int numBins,
+                           int x)
+{
+    int min;
+    int max;
+    int mid;
+
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectS32", 4,
+            "---- Calling p_psVectorBinDisectS32(%f)\n", x);
+
+    if ((x < bins[0]) ||
+            (x > bins[numBins-1])) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "p_psVectorBinDisectS32(): ordinate %f is outside vector range (%f - %f).",
+                 x, bins[0], bins[numBins-1]);
+        return(-1);
+    }
+
+    min = 0;
+    max = numBins-2;
+    mid = ((max+1)-min)/2;
+
+    while (min != max) {
+        psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectS32", 4,
+                "(min, mid, max) is (%d, %d, %d): (x, bins) is (%f, %f)\n",
+                min, mid, max, x, bins[mid]);
+
+        if (x == bins[mid]) {
+            psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectS32", 4,
+                    "---- Exiting p_psVectorBinDisectS32(): bin %d\n", min);
+            return(min);
+        } else if (x < bins[mid]) {
+            max = mid-1;
+        } else {
+            min = mid;
+        }
+        mid = ((max+1)+min)/2;
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectS32", 4,
+            "---- Exiting p_psVectorBinDisectS32(): bin %d\n", min);
+    return(min);
+}
+
+/*****************************************************************************
+p_psVectorBinDisect(): A wrapper to the above p_psVectorBinDisect().
+ *****************************************************************************/
+int p_psVectorBinDisect(psVector *bins,
+                        psScalar *x)
+{
+    if (x->type.type != bins->type.type) {
+        psError(__func__, "x->type.type != bins->type.type");
+        return(-2);
+    }
+
+    if (x->type.type == PS_TYPE_S32) {
+        return(p_psVectorBinDisectS32(bins->data.S32, bins->n, x->data.S32));
+    } else if (x->type.type == PS_TYPE_F32) {
+        return(p_psVectorBinDisectF32(bins->data.F32, bins->n, x->data.F32));
+    } else {
+        psError(__func__, "Unallowable data type.");
+        return(-2);
+    }
+    return(-1);
+}
+
+/*****************************************************************************
+p_psInterpolate1D(): This routine will take as input n-element floating
+point arrays domain and range, and the x value, assumed to lie with the
+domain vector.  It produces as output the (n-1)-order LaGrange interpolated
+value of x.
+ 
+XXX: do we error check for non-distinct domain values?
+ *****************************************************************************/
+float p_ps1DFullInterpolateF32(float *domain,
+                               float *range,
+                               int n,
+                               float x)
+{
+    int i;
+    int m;
+    static psVector *p = NULL;
+    p = psVectorRecycle(p, n, PS_TYPE_F32);
+    p_psMemSetPersistent(p, true);
+    p_psMemSetPersistent(p->data.F32, true);
+    /*
+        psVector *p = psVectorAlloc(n, PS_TYPE_F32);
+        float tmp;
+    */
+
+    psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 4,
+            "---- p_ps1DFullInterpolateF32() begin (%d-order at x=%f) (%d data points)----\n", n-1, x, n);
+
+    for (i=0;i<n;i++) {
+        psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 6,
+                "domain/range is (%f %f)\n", domain[i], range[i]);
+    }
+
+    for (i=0;i<n;i++) {
+        p->data.F32[i] = range[i];
+        psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 6,
+                "p->data.F32[%d] is %f\n", i, p->data.F32[i]);
+
+    }
+
+    // From NR, during each iteration of the m loop, we are computing the
+    // p_{i ... i+m} terms.
+    for (m=1;m<n;m++) {
+        for (i=0;i<n-m;i++) {
+            // From NR: we are computing P_{i ... i+m}
+            p->data.F32[i] = (((x-domain[i+m]) * p->data.F32[i]) +
+                              ((domain[i]-x) * p->data.F32[i+1])) /
+                             (domain[i] - domain[i+m]);
+            //printf("((%f-%f * %f) + (%f-%f * %f)) / (%f - %f)\n", x, domain[i+m], p->data.F32[i], domain[i], x, p->data.F32[i+1], domain[i], domain[i+m]);
+            psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 6,
+                    "p->data.F32[%d] is %f\n", i, p->data.F32[i]);
+        }
+    }
+    psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 4,
+            "---- p_ps1DFullInterpolateF32() end ----\n");
+
+    /*
+        tmp = p->data.F32[0];
+        psFree(p);
+        return(tmp);
+    */
+    return(p->data.F32[0]);
+}
+
+
+/*****************************************************************************
+p_ps1DInterpolateF32(): this is the base 1-D flat memory routine to perform
+LaGrange interpolation.
+ *****************************************************************************/
+float p_ps1DInterpolateF32(float *domain,
+                           float *range,
+                           int n,
+                           int order,
+                           float x)
+{
+    int binNum;
+    int numIntPoints = order+1;
+    int origin;
+
+    psTrace(".psLib.dataManip.psFunctions.p_ps1DInterpolateF32", 4,
+            "---- p_ps1DInterpolateF32() begin ----\n");
+
+    binNum = p_psVectorBinDisectF32(domain, n, x);
+
+    if (0 == numIntPoints%2) {
+        origin = binNum - ((numIntPoints/2) - 1);
+    } else {
+        origin = binNum - (numIntPoints/2);
+        if ((x-domain[binNum]) > (domain[binNum+1]-x)) {
+            // x is closer to binNum+1.
+            origin = 1 + (binNum - (numIntPoints/2));
+        }
+    }
+    if (origin < 0) {
+        origin = 0;
+    }
+    if ((origin + numIntPoints) > n) {
+        origin = n - numIntPoints;
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.p_ps1DInterpolateF32", 4,
+            "---- p_ps1DInterpolateF32() end ----\n");
+    return(p_ps1DFullInterpolateF32(&domain[origin], &range[origin], order+1, x));
+}
+
+/*****************************************************************************
+p_psVectorInterpolate(): This routine will take as input psVectors domain and
+range, and the x value, assumed to lie with the domain vector.  It produces
+as output the LaGrange interpolated value of a polynomial of the specified
+order around the point x.
+ 
+XXX: This stuff does not currently work with a mask.
+ 
+XXX: nobody asked for us to generate this routine.
+ 
+XXX: add another psScalar argument for the result.
+ 
+XXX: The VectorCopy routines seg fault when I declare range32 as static.
+ *****************************************************************************/
+psScalar *p_psVectorInterpolate(psVector *domain,
+                                psVector *range,
+                                int order,
+                                psScalar *x)
+{
+    psVector *range32 = NULL;
+    psVector *domain32 = NULL;
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+            "---- p_psVectorInterpolate() begin ----\n");
+
+    if ((domain->type.type != range->type.type) ||
+            (domain->type.type != x->type.type)) {
+        // XXX psError
+        printf("p_psVectorInterpolate(): domain->type.type != range->type.type != x->type.type\n");
+        printf("%d %d %d\n", domain->type.type, range->type.type, x->type.type);
+        exit(1);
+    }
+    if (domain->n != range->n) {
+        // XXX psError
+        printf("domain->n != range->n\n");
+        exit(1);
+    }
+    if (order > (domain->n - 1)) {
+        // XXX psError: not enough data points for order-order interpolation.
+        printf("not enough data points for order-order interpolation.\n");
+        exit(1);
+    }
+
+    if (x->type.type == PS_TYPE_F32) {
+        psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+                "---- p_psVectorInterpolate() end ----\n");
+        return(psScalarAlloc(p_ps1DInterpolateF32(domain->data.F32,
+                             range->data.F32,
+                             domain->n,
+                             order,
+                             x->data.F32), PS_TYPE_F32));
+    } else if (x->type.type == PS_TYPE_F64) {
+        // XXX: use recycled vectors here.
+        range32 = psVectorCopy(range32, range, PS_TYPE_F32);
+        domain32 = psVectorCopy(domain32, domain, PS_TYPE_F32);
+
+        psScalar *tmpScalar = psScalarAlloc((double)
+                                            p_ps1DInterpolateF32(domain32->data.F32,
+                                                                 range32->data.F32,
+                                                                 domain32->n,
+                                                                 order,
+                                                                 (float) x->data.F64), PS_TYPE_F64);
+        psFree(range32);
+        psFree(domain32);
+
+        psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+                "---- p_psVectorInterpolate() end ----\n");
+        // XXX: Convert data type to F64?
+        return(tmpScalar);
+
+    } else {
+        // XXX psError: type not supported
+        printf("XXX psError: type not supported\n");
+    }
+
+    printf("return(NULL)\n");
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+            "---- p_psVectorInterpolate() end ----\n");
+    return(NULL);
+}
+
+
+/*****************************************************************************
+psSpline1DEval(): this routine takes an existing spline of arbitrary order
+and an independent x value.  Each determines which spline that x corresponds
+to by doing a bracket disection on the domains of the spline data structure
+(p_psVectorBinDisectF32()).  Then it evaluates the spline at that x location
+by a call to the 1D polynomial functions.
+ 
+XXX: The spline eval functions require input and output to be F32.  however
+     the spline fit functions require F32 and F64.
+ *****************************************************************************/
+float psSpline1DEval(const psSpline1D *spline,
+                     float x)
+{
+    int binNum;
+    int n;
+
+    n = spline->n;
+    binNum = p_psVectorBinDisectF32(spline->domains, (spline->n)+1, x);
+    if (binNum < 0) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "psSpline1DEval(): x ordinate (%f) is outside the spline range (%f - %f).",
+                 x, (spline->domains)[0],
+                 (spline->domains)[n-1]);
+
+        if (x < (spline->domains)[0]) {
+            return(psPolynomial1DEval(x, spline->spline[0]));
+        } else if (x > (spline->domains)[n-1]) {
+            return(psPolynomial1DEval(x, spline->spline[n-1]));
+        }
+    }
+
+    return(psPolynomial1DEval(x, spline->spline[binNum]));
+}
+
+// XXX: The spline eval functions require input and output to be F32.
+// however the spline fit functions require F32 and F64.
+psVector *psSpline1DEvalVector(const psVector *x,
+                               const psSpline1D *spline)
+{
+    int i;
+    psVector *tmpVector;
+
+    tmpVector = psVectorAlloc(x->n, PS_TYPE_F32);
+    if (x->type.type == PS_TYPE_F32) {
+        for (i=0;i<x->n;i++) {
+            tmpVector->data.F32[i] = psSpline1DEval(spline, x->data.F32[i]);
+        }
+    } else if (x->type.type == PS_TYPE_F64) {
+        for (i=0;i<x->n;i++) {
+            tmpVector->data.F32[i] = psSpline1DEval(spline, (float) x->data.F64[i]);
+        }
+    } else {
+        psError(__func__, "Unknown data type.\n");
+        return(NULL);
+    }
+
+    return(tmpVector);
+}
Index: /branches/rel3/psLib/src/math/psPolynomial.h
===================================================================
--- /branches/rel3/psLib/src/math/psPolynomial.h	(revision 2163)
+++ /branches/rel3/psLib/src/math/psPolynomial.h	(revision 2163)
@@ -0,0 +1,435 @@
+/** @file psFunctions.h
+*  \brief Standard Mathematical Functions.
+*  \ingroup Stats
+*
+*  This file will hold the prototypes for procedures which allocate, free,
+*  and evaluate various polynomials.  Those polynomial structures are also
+*  defined here.
+*
+*  @ingroup Stats
+*
+*  @author Someone at IfA
+*  @author George Gusciora, MHPCC
+*
+*  @version $Revision: 1.30 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-06 00:48:15 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#if !defined(PS_FUNCTIONS_H)
+#define PS_FUNCTIONS_H
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <float.h>
+#include <math.h>
+
+#include "psVector.h"
+#include "psScalar.h"
+
+/** \addtogroup Stats
+ *  \{
+ */
+
+/** Evaluate a non-normalized Gaussian with the given mean and sigma at the
+ *  given coordianate.  
+ *
+ *  Note that this is not a Gaussian deviate.  The evaluated Gaussian is: 
+ *        \f[ exp(-\frac{(x-mean)^2}{2\sigma^2}) \f] 
+ *
+ *  @return float      value on the gaussian curve given the input parameters
+ */
+float psGaussian(
+    float x,                           ///< Value at which to evaluate
+    float mean,                        ///< Mean for the Gaussian
+    float stddev,                      ///< Standard deviation for the Gaussian
+    bool normal                        ///< Indicates whether result should be normalized
+);
+
+/** Produce a vector of random numbers from a Gaussian distribution with
+ *  the specified mean and sigma 
+ *  
+ *  @return psVector*    vector of random numbers
+ *  
+ */
+psVector* psGaussianDev(
+    float mean,                        ///< The mean of the Gaussian
+    float sigma,                       ///< The sigma of the Gaussian
+    int Npts                           ///< The size of the vector
+);
+
+typedef enum {
+    PS_POLYNOMIAL_ORD,                 ///< Ordinary Polynomial
+    PS_POLYNOMIAL_CHEB                 ///< Chebyshev Polynomial
+} psPolynomialType;
+
+/** One-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int n;                             ///< Number of terms
+    float *coeff;                      ///< Coefficients
+    float *coeffErr;                   ///< Error in coefficients
+    char *mask;                        ///< Coefficient mask
+}
+psPolynomial1D;
+
+/** Two-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    float **coeff;                     ///< Coefficients
+    float **coeffErr;                  ///< Error in coefficients
+    char **mask;                       ///< Coefficients mask
+}
+psPolynomial2D;
+
+/** Three-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    int nZ;                            ///< Number of terms in z
+    float ***coeff;                    ///< Coefficients
+    float ***coeffErr;                 ///< Error in coefficients
+    char ***mask;                      ///< Coefficients mask
+}
+psPolynomial3D;
+
+/** Four-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nW;                            ///< Number of terms in w
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    int nZ;                            ///< Number of terms in z
+    float ****coeff;                   ///< Coefficients
+    float ****coeffErr;                ///< Error in coefficients
+    char ****mask;                     ///< Coefficients mask
+}
+psPolynomial4D;
+
+
+/** Allocates a psPolynomial1D structure with n terms
+ *
+ *  @return  psPolynomial1D*    new 1-D polynomial struct
+ */
+psPolynomial1D* psPolynomial1DAlloc(
+    int n,                              ///< Number of terms
+    psPolynomialType type               ///< Polynomial Type
+);
+
+/** Allocates a 2-D polynomial structure
+ *
+ *  @return  psPolynomial2D*    new 2-D polynomial struct
+ */
+psPolynomial2D* psPolynomial2DAlloc(
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Allocates a 3-D polynomial structure
+ *
+ *  @return  psPolynomial3D*    new 3-D polynomial struct
+ */
+psPolynomial3D* psPolynomial3DAlloc(
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    int nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Allocates a 4-D polynomial structure
+ *
+ *  @return  psPolynomial4D*    new 4-D polynomial struct
+ */
+psPolynomial4D* psPolynomial4DAlloc(
+    int nW,                            ///< Number of terms in w
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    int nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Evaluates a 1-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+float psPolynomial1DEval(
+    float x,                           ///< location at which to evaluate
+    const psPolynomial1D* myPoly       ///< Coefficients for the polynomial
+);
+
+/** Evaluates a 2-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+float psPolynomial2DEval(
+    float x,                           ///< x location at which to evaluate
+    float y,                           ///< y location at which to evaluate
+    const psPolynomial2D* myPoly       ///< Coefficients for the polynomial
+);
+
+/** Evaluates a 3-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+float psPolynomial3DEval(
+    float x,                           ///< x location at which to evaluate
+    float y,                           ///< y location at which to evaluate
+    float z,                           ///< z location at which to evaluate
+    const psPolynomial3D* myPoly       ///< Coefficients for the polynomial
+);
+
+/** Evaluates a 4-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+float psPolynomial4DEval(
+    float w,                           ///< w location at which to evaluate
+    float x,                           ///< x location at which to evaluate
+    float y,                           ///< y location at which to evaluate
+    float z,                           ///< z location at which to evaluate
+    const psPolynomial4D* myPoly       ///< Coefficients for the polynomial
+);
+
+psVector *psPolynomial1DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                   const psPolynomial1D *myPoly   ///< Coefficients for the polynomial
+                                  );
+
+psVector *psPolynomial2DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                   const psVector *y,             ///< y locations at which to evaluate
+                                   const psPolynomial2D *myPoly   ///< Coefficients for the polynomial
+                                  );
+
+psVector *psPolynomial3DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                   const psVector *y,             ///< y locations at which to evaluate
+                                   const psVector *z,             ///< z locations at which to evaluate
+                                   const psPolynomial3D *myPoly   ///< Coefficients for the polynomial
+                                  );
+
+psVector *psPolynomial4DEvalVector(const psVector *w,             ///< w locations at which to evaluate
+                                   const psVector *x,             ///< x locations at which to evaluate
+                                   const psVector *y,             ///< y locations at which to evaluate
+                                   const psVector *z,             ///< z locations at which to evaluate
+                                   const psPolynomial4D *myPoly   ///< Coefficients for the polynomial
+                                  );
+
+/*****************************************************************************/
+
+/* Double-precision polynomials, mainly for use in astrometry */
+
+/** Double-precision one-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int n;                             ///< Number of terms
+    double *coeff;                     ///< Coefficients
+    double *coeffErr;                  ///< Error in coefficients
+    char *mask;                        ///< Coefficient mask
+}
+psDPolynomial1D;
+
+/** Double-precision two-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    double **coeff;                    ///< Coefficients
+    double **coeffErr;                 ///< Error in coefficients
+    char **mask;                       ///< Coefficients mask
+}
+psDPolynomial2D;
+
+/** Double-precision three-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    int nZ;                            ///< Number of terms in z
+    double ***coeff;                   ///< Coefficients
+    double ***coeffErr;                ///< Error in coefficients
+    char ***mask;                      ///< Coefficient mask
+}
+psDPolynomial3D;
+
+/** Double-precision four-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nW;                            ///< Number of terms in w
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    int nZ;                            ///< Number of terms in z
+    double ****coeff;                  ///< Coefficients
+    double ****coeffErr;               ///< Error in coefficients
+    char ****mask;                     ///< Coefficients mask
+}
+psDPolynomial4D;
+
+/** Allocates a double-precision 1-D polynomial structure with n terms
+ *
+ *  @return  psPolynomial1D*    new double-precision 1-D polynomial struct
+ */
+psDPolynomial1D* psDPolynomial1DAlloc(
+    int n,                             ///< Number of terms
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Allocates a double-precision 2-D polynomial structure
+ *
+ *  @return  psPolynomial2D*    new double-precision 2-D polynomial struct
+ */
+psDPolynomial2D* psDPolynomial2DAlloc(
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Allocates a double-precision 3-D polynomial structure
+ *
+ *  @return  psPolynomial3D*    new double-precision 3-D polynomial struct
+ */
+psDPolynomial3D* psDPolynomial3DAlloc(
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    int nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Allocates a double-precision 4-D polynomial structure
+ *
+ *  @return  psPolynomial4D*    new double-precision 4-D polynomial struct
+ */
+psDPolynomial4D* psDPolynomial4DAlloc(
+    int nW,                            ///< Number of terms in w
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    int nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Evaluates a double-precision 1-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+double psDPolynomial1DEval(
+    double x,                          ///< Value at which to evaluate
+    const psDPolynomial1D* myPoly      ///< Coefficients for the polynomial
+);
+
+/** Evaluates a double-precision 2-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+double psDPolynomial2DEval(
+    double x,                           ///< Value x at which to evaluate
+    double y,                           ///< Value y at which to evaluate
+    const psDPolynomial2D* myPoly       ///< Coefficients for the polynomial
+);
+
+/** Evaluates a double-precision 3-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+double psDPolynomial3DEval(
+    double x,                          ///< Value x at which to evaluate
+    double y,                          ///< Value y at which to evaluate
+    double z,                          ///< Value z at which to evaluate
+    const psDPolynomial3D* myPoly      ///< Coefficients for the polynomial
+);
+
+/** Evaluates a double-precision 4-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+double psDPolynomial4DEval(
+    double w,                          ///< Value w at which to evaluate
+    double x,                          ///< Value x at which to evaluate
+    double y,                          ///< Value y at which to evaluate
+    double z,                          ///< Value z at which to evaluate
+    const psDPolynomial4D* myPoly      ///< Coefficients for the polynomial
+);
+
+psVector *psDPolynomial1DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                    const psDPolynomial1D *myPoly  ///< Coefficients for the polynomial
+                                   );
+
+psVector *psDPolynomial2DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                    const psVector *y,             ///< y locations at which to evaluate
+                                    const psDPolynomial2D *myPoly  ///< Coefficients for the polynomial
+                                   );
+
+psVector *psDPolynomial3DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                    const psVector *y,             ///< y locations at which to evaluate
+                                    const psVector *z,             ///< z locations at which to evaluate
+                                    const psDPolynomial3D *myPoly  ///< Coefficients for the polynomial
+                                   );
+
+psVector *psDPolynomial4DEvalVector(const psVector *w,             ///< w locations at which to evaluate
+                                    const psVector *x,             ///< x locations at which to evaluate
+                                    const psVector *y,             ///< y locations at which to evaluate
+                                    const psVector *z,             ///< z locations at which to evaluate
+                                    const psDPolynomial4D *myPoly  ///< Coefficients for the polynomial
+                                   );
+
+
+
+typedef struct
+{
+    int n;                        ///< The number of spline polynomials
+    psPolynomial1D **spline;      ///< An array of n pointers to the spline polynomials
+    float *p_psDeriv2;            ///< For cubic splines, the second derivative at each domain point.  Size is n+1.
+    float *domains;               ///< The boundaries between each spline piece.  Size is n+1.
+}
+psSpline1D;
+
+psSpline1D *psSpline1DAlloc(int n,
+                            int order,
+                            float min,
+                            float max);
+
+int p_psSpline1DFree(psSpline1D *tmpSpline);
+
+psSpline1D *psSpline1DAllocGeneric(const psVector *bounds,
+                                   int order);
+
+float psSpline1DEval(const psSpline1D *spline,
+                     float x);
+
+psVector *psSpline1DEvalVector(const psVector *x,
+                               const psSpline1D *spline);
+
+int p_psVectorBinDisectF32(float *bins,
+                           int numBins,
+                           float x);
+
+int p_psVectorBinDisectS32(int *bins,
+                           int numBins,
+                           int x);
+
+int p_psVectorBinDisect(psVector *bins,
+                        psScalar *x);
+
+psScalar *p_psVectorInterpolate(psVector *domain,
+                                psVector *range,
+                                int order,
+                                psScalar *x);
+
+float p_psNRSpline1DEval(psSpline1D *spline,
+                         const psVector* restrict x,
+                         const psVector* restrict y,
+                         float X);
+
+/* \} */// End of MathGroup Functions
+
+#endif
+
Index: /branches/rel3/psLib/src/math/psSpline.c
===================================================================
--- /branches/rel3/psLib/src/math/psSpline.c	(revision 2163)
+++ /branches/rel3/psLib/src/math/psSpline.c	(revision 2163)
@@ -0,0 +1,2111 @@
+/** @file  psFunctions.c
+ *
+ *  @brief Contains basic function allocation, deallocation, and evaluation
+ *         routines.
+ *
+ *  This file will hold the functions for allocated, freeing, and evaluating
+ *  polynomials.  It also contains a Gaussian functions.
+ *
+ *  @version $Revision: 1.52 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 01:44:48 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+/*****************************************************************************/
+/*  INCLUDE FILES                                                            */
+/*****************************************************************************/
+#include <gsl/gsl_rng.h>
+#include <gsl/gsl_randist.h>
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <float.h>
+#include <math.h>
+
+#include "psMemory.h"
+#include "psVector.h"
+#include "psScalar.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psLogMsg.h"
+
+#include "psFunctions.h"
+/*****************************************************************************/
+/* DEFINE STATEMENTS                                                         */
+/*****************************************************************************/
+/*
+ * The following macros take the vector IN as input.  If IN is not of
+ * the correct type, then a new vector OUT is created of the correct
+ * type, and the elements of IN and converted to OUT.
+ *
+ * If vector IN is the correct type, then OUT is simply set to IN.
+ */
+#define PS_CONVERT_VECTOR_F32(IN, OUT) \
+if (IN->type.type != PS_TYPE_F32) { \
+    psLogMsg(__func__, PS_LOG_WARN, \
+             "Input vector has incorrect type (%d).\n", \
+             IN->type); \
+    OUT = psVectorAlloc(IN->n, PS_TYPE_F32); \
+    \
+    if (IN->type.type == PS_TYPE_F64) { \
+        for (int i=0;i<IN->n;i++) { \
+            OUT->data.F32[i] = (float) (IN->data.F64[i]); \
+        } \
+    }\
+    else { \
+        psAbort(__func__, "Wrong type.\n"); \
+    } \
+} else { \
+    OUT = (psVector *) IN; \
+}
+
+#define PS_CONVERT_VECTOR_F64(IN, OUT) \
+if (IN->type.type != PS_TYPE_F64) { \
+    psLogMsg(__func__, PS_LOG_WARN, \
+             "Input vector has incorrect type (%d).\n", \
+             IN->type); \
+    OUT = psVectorAlloc(IN->n, PS_TYPE_F64); \
+    \
+    if (IN->type.type == PS_TYPE_F32) { \
+        for (int i=0;i<IN->n;i++) { \
+            OUT->data.F64[i] = (float) (IN->data.F32[i]); \
+        } \
+    }\
+    else { \
+        psAbort(__func__, "Wrong type.\n"); \
+    } \
+} else { \
+    OUT = (psVector *) IN; \
+}
+
+/*****************************************************************************/
+/* TYPE DEFINITIONS                                                          */
+/*****************************************************************************/
+static void polynomial1DFree(psPolynomial1D* myPoly);
+static void polynomial2DFree(psPolynomial2D* myPoly);
+static void polynomial3DFree(psPolynomial3D* myPoly);
+static void polynomial4DFree(psPolynomial4D* myPoly);
+static void dPolynomial1DFree(psDPolynomial1D* myPoly);
+static void dPolynomial2DFree(psDPolynomial2D* myPoly);
+static void dPolynomial3DFree(psDPolynomial3D* myPoly);
+static void dPolynomial4DFree(psDPolynomial4D* myPoly);
+
+/*****************************************************************************/
+/* GLOBAL VARIABLES                                                          */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FILE STATIC VARIABLES                                                     */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - LOCAL                                           */
+/*****************************************************************************/
+
+/*****************************************************************************
+CreateChebyshevPolys(n): this routine takes as input the required order n,
+and returns as output as a pointer to an array of n psPolynomial1D
+structures, corresponding to the first n Chebyshev polynomials.
+ 
+XXX: The output should be static since the Chebyshev polynomials might be
+used frequently and the data structure created here does not contain the
+outer coefficients of the Chebyshev polynomials.
+ *****************************************************************************/
+static psPolynomial1D **CreateChebyshevPolys(int maxChebyPoly)
+{
+    psPolynomial1D **chebPolys = NULL;
+    int i = 0;
+    int j = 0;
+
+    chebPolys = (psPolynomial1D **) psAlloc(maxChebyPoly * sizeof(psPolynomial1D *));
+    for (i = 0; i < maxChebyPoly; i++) {
+        chebPolys[i] = psPolynomial1DAlloc(i + 1, PS_POLYNOMIAL_ORD);
+    }
+
+    // Create the Chebyshev polynomials.
+    // Polynomial i has i-th order.
+    chebPolys[0]->coeff[0] = 1;
+    chebPolys[1]->coeff[1] = 1;
+    for (i = 2; i < maxChebyPoly; i++) {
+        for (j = 0; j < chebPolys[i - 1]->n; j++) {
+            chebPolys[i]->coeff[j + 1] = 2 * chebPolys[i - 1]->coeff[j];
+        }
+        for (j = 0; j < chebPolys[i - 2]->n; j++) {
+            chebPolys[i]->coeff[j] -= chebPolys[i - 2]->coeff[j];
+        }
+    }
+
+    return (chebPolys);
+}
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - PUBLIC                                         */
+/*****************************************************************************/
+
+/*****************************************************************************
+    Evaluate a non-normalized Gaussian with the given mean and sigma at the
+    given coordianate.  Note that this is not a Gaussian deviate.  The
+    evaluated Gaussian is: \f[ exp(-\frac{(x-mean)^2}{2\sigma^2}) \f]
+ *****************************************************************************/
+float psGaussian(float x, float mean, float sigma, bool normal)
+{
+    float tmp = 1.0;
+
+    psTrace(".psLib.dataManip.psFunctions.psGaussian", 4,
+            "---- psGaussian() begin ----\n");
+
+    if (normal == true) {
+        #ifdef DARWIN
+        tmp = 1.0 / (float)sqrt(2.0 * M_PI * (sigma * sigma));
+        #else
+
+        tmp = 1.0 / sqrtf(2.0 * M_PI * (sigma * sigma));
+        #endif
+
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.psGaussian", 4,
+            "---- psGaussian() end ----\n");
+    return(tmp * exp(-((x - mean) * (x - mean)) / (2.0 * sigma * sigma)));
+}
+
+/*****************************************************************************
+    psGaussianDev()
+ This routine creates a psVector of the specified size and type F32
+ and fills it with a random Gaussian distribution of numbers with
+ the specified mean and sigma.  This routine makes use of the GSL
+ routines for generating both uniformly distributed numbers and the
+ Gaussian distribution as well.
+ 
+ NOTE: XXX: There is no way to seed the random generator.
+ *****************************************************************************/
+psVector* psGaussianDev(float mean, float sigma, int Npts)
+{
+    psVector* gauss = NULL;
+    const gsl_rng_type *T = NULL;
+    gsl_rng *r = NULL;
+    int i = 0;
+
+    gauss = psVectorAlloc(Npts, PS_TYPE_F32);
+    gauss->n = Npts;
+    gsl_rng_env_setup();
+    T = gsl_rng_default;
+    r = gsl_rng_alloc(T);
+
+    for (i = 0; i < Npts; i++) {
+        gauss->data.F32[i] = mean + gsl_ran_gaussian(r, sigma);
+    }
+
+    // NOTE: Should I free r as well?
+    return(gauss);
+}
+
+/*****************************************************************************
+    This routine must allocate memory for the polynomial structures.
+ *****************************************************************************/
+psPolynomial1D* psPolynomial1DAlloc(int n,
+                                    psPolynomialType type)
+{
+    int i = 0;
+    psPolynomial1D* newPoly = NULL;
+
+    newPoly = (psPolynomial1D* ) psAlloc(sizeof(psPolynomial1D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) polynomial1DFree);
+
+    newPoly->type = type;
+    newPoly->n = n;
+    newPoly->coeff = (float *)psAlloc(n * sizeof(float));
+    newPoly->coeffErr = (float *)psAlloc(n * sizeof(float));
+    newPoly->mask = (char *)psAlloc(n * sizeof(char));
+    for (i = 0; i < n; i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0;
+    }
+
+    return(newPoly);
+}
+
+psPolynomial2D* psPolynomial2DAlloc(int nX, int nY,
+                                    psPolynomialType type)
+{
+    int x = 0;
+    int y = 0;
+    psPolynomial2D* newPoly = NULL;
+
+    newPoly = (psPolynomial2D* ) psAlloc(sizeof(psPolynomial2D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) polynomial2DFree);
+
+    newPoly->type = type;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+
+    newPoly->coeff = (float **)psAlloc(nX * sizeof(float *));
+    newPoly->coeffErr = (float **)psAlloc(nX * sizeof(float *));
+    newPoly->mask = (char **)psAlloc(nX * sizeof(char *));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (float *)psAlloc(nY * sizeof(float));
+        newPoly->coeffErr[x] = (float *)psAlloc(nY * sizeof(float));
+        newPoly->mask[x] = (char *)psAlloc(nY * sizeof(char));
+    }
+    for (x = 0; x < nX; x++) {
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = 0.0;
+            newPoly->coeffErr[x][y] = 0.0;
+            newPoly->mask[x][y] = 0;
+        }
+    }
+
+    return(newPoly);
+}
+
+psPolynomial3D* psPolynomial3DAlloc(int nX, int nY, int nZ,
+                                    psPolynomialType type)
+{
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psPolynomial3D* newPoly = NULL;
+
+    newPoly = (psPolynomial3D* ) psAlloc(sizeof(psPolynomial3D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) polynomial3DFree);
+
+    newPoly->type = type;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff = (float ***)psAlloc(nX * sizeof(float **));
+    newPoly->coeffErr = (float ***)psAlloc(nX * sizeof(float **));
+    newPoly->mask = (char ***)psAlloc(nX * sizeof(char **));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (float **)psAlloc(nY * sizeof(float *));
+        newPoly->coeffErr[x] = (float **)psAlloc(nY * sizeof(float *));
+        newPoly->mask[x] = (char **)psAlloc(nY * sizeof(char *));
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = (float *)psAlloc(nZ * sizeof(float));
+            newPoly->coeffErr[x][y] = (float *)psAlloc(nZ * sizeof(float));
+            newPoly->mask[x][y] = (char *)psAlloc(nZ * sizeof(char));
+        }
+    }
+    for (x = 0; x < nX; x++) {
+        for (y = 0; y < nY; y++) {
+            for (z = 0; z < nZ; z++) {
+                newPoly->coeff[x][y][z] = 0.0;
+                newPoly->coeffErr[x][y][z] = 0.0;
+                newPoly->mask[x][y][z] = 0;
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+psPolynomial4D* psPolynomial4DAlloc(int nW, int nX, int nY, int nZ,
+                                    psPolynomialType type)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psPolynomial4D* newPoly = NULL;
+
+    newPoly = (psPolynomial4D* ) psAlloc(sizeof(psPolynomial4D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) polynomial4DFree);
+
+    newPoly->type = type;
+    newPoly->nW = nW;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff = (float ****)psAlloc(nW * sizeof(float ***));
+    newPoly->coeffErr = (float ****)psAlloc(nW * sizeof(float ***));
+    newPoly->mask = (char ****)psAlloc(nW * sizeof(char ***));
+    for (w = 0; w < nW; w++) {
+        newPoly->coeff[w] = (float ***)psAlloc(nX * sizeof(float **));
+        newPoly->coeffErr[w] = (float ***)psAlloc(nX * sizeof(float **));
+        newPoly->mask[w] = (char ***)psAlloc(nX * sizeof(char **));
+        for (x = 0; x < nX; x++) {
+            newPoly->coeff[w][x] = (float **)psAlloc(nY * sizeof(float *));
+            newPoly->coeffErr[w][x] = (float **)psAlloc(nY * sizeof(float *));
+            newPoly->mask[w][x] = (char **)psAlloc(nY * sizeof(char *));
+            for (y = 0; y < nY; y++) {
+                newPoly->coeff[w][x][y] = (float *)psAlloc(nZ * sizeof(float));
+                newPoly->coeffErr[w][x][y] = (float *)psAlloc(nZ * sizeof(float));
+                newPoly->mask[w][x][y] = (char *)psAlloc(nZ * sizeof(char));
+            }
+        }
+    }
+    for (w = 0; w < nW; w++) {
+        for (x = 0; x < nX; x++) {
+            for (y = 0; y < nY; y++) {
+                for (z = 0; z < nZ; z++) {
+                    newPoly->coeff[w][x][y][z] = 0.0;
+                    newPoly->coeffErr[w][x][y][z] = 0.0;
+                    newPoly->mask[w][x][y][z] = 0;
+                }
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+static void polynomial1DFree(psPolynomial1D* myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void polynomial2DFree(psPolynomial2D* myPoly)
+{
+    int x = 0;
+
+    for (x = 0; x < myPoly->nX; x++) {
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void polynomial3DFree(psPolynomial3D* myPoly)
+{
+    int x = 0;
+    int y = 0;
+
+    for (x = 0; x < myPoly->nX; x++) {
+        for (y = 0; y < myPoly->nY; y++) {
+            psFree(myPoly->coeff[x][y]);
+            psFree(myPoly->coeffErr[x][y]);
+            psFree(myPoly->mask[x][y]);
+        }
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void polynomial4DFree(psPolynomial4D* myPoly)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+
+    for (w = 0; w < myPoly->nW; w++) {
+        for (x = 0; x < myPoly->nX; x++) {
+            for (y = 0; y < myPoly->nY; y++) {
+                psFree(myPoly->coeff[w][x][y]);
+                psFree(myPoly->coeffErr[w][x][y]);
+                psFree(myPoly->mask[w][x][y]);
+            }
+            psFree(myPoly->coeff[w][x]);
+            psFree(myPoly->coeffErr[w][x]);
+            psFree(myPoly->mask[w][x]);
+        }
+        psFree(myPoly->coeff[w]);
+        psFree(myPoly->coeffErr[w]);
+        psFree(myPoly->mask[w]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ 
+    XXX: Should the "coeffErr[]" should be used as well?
+ *****************************************************************************/
+float p_psOrdPolynomial1DEval(float x, const psPolynomial1D* myPoly)
+{
+    int loop_x = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+
+    psTrace(".psLib.dataManip.psFunctions.p_psOrdPolynomial1DEval", 4,
+            "---- Calling p_psOrdPolynomial1DEval(%f)\n", x);
+    psTrace(".psLib.dataManip.psFunctions.p_psOrdPolynomial1DEval", 4,
+            "Polynomial order is %d\n", myPoly->n);
+    for (loop_x = 0; loop_x < myPoly->n; loop_x++) {
+        psTrace(".psLib.dataManip.psFunctions.p_psOrdPolynomial1DEval", 4,
+                "Polynomial coeff[%d] is %f\n", loop_x, myPoly->coeff[loop_x]);
+    }
+
+
+    if (NULL == myPoly) {
+        psAbort(__func__, "psPolynomial1DEval(): myPoly is NULL\n");
+    }
+
+    // NOTE: Do we want to flag this case?
+    if (myPoly->n == 0) {
+        return(1.0);
+    }
+
+    if (NULL == myPoly->coeff) {
+        psAbort(__func__, "psPolynomial1DEval(): myPoly->coeff is NULL\n");
+    }
+
+    for (loop_x = 0; loop_x < myPoly->n; loop_x++) {
+        if (myPoly->mask[loop_x] == 0) {
+            psTrace(".psLib.dataManip.psFunctions.p_psOrdPolynomial1DEval", 10,
+                    "polysum+= sum*coeff [%f+= (%f * %f)\n", polySum, xSum, myPoly->coeff[loop_x]);
+            polySum += xSum * myPoly->coeff[loop_x];
+            xSum *= x;
+        }
+    }
+
+    return(polySum);
+}
+
+// XXX: You can do this without having to psAlloc() vector d.
+// XXX: How does the mask vector effect Crenshaw's formula?
+float p_psChebPolynomial1DEval(float x, const psPolynomial1D* myPoly)
+{
+    psVector *d;
+    int n;
+    int i;
+    float tmp;
+
+    n = myPoly->n;
+    d = psVectorAlloc(n, PS_TYPE_F32);
+    d->data.F32[n-1] = myPoly->coeff[n-1];
+    d->data.F32[n-2] = (2.0 * x * d->data.F32[n-1]) + myPoly->coeff[n-2];
+    for (i=n-3;i>=1;i--) {
+        d->data.F32[i] = (2.0 * x * d->data.F32[i+1]) -
+                         (d->data.F32[i+2]) +
+                         (myPoly->coeff[i]);
+    }
+
+    tmp = (x * d->data.F32[1]) -
+          (d->data.F32[2]) +
+          (0.5 * myPoly->coeff[0]);
+
+    psFree(d);
+    return(tmp);
+    /*
+
+    int n;
+    int i;
+    float tmp;
+    psPolynomial1D **chebPolys = NULL;
+
+    n = myPoly->n;
+    chebPolys = CreateChebyshevPolys(n);
+
+    tmp = 0.0;
+    for (i=0;i<myPoly->n;i++) {
+        tmp+= (myPoly->coeff[i] * psPolynomial1DEval(x, chebPolys[i]));
+        //            printf("HMMM: psPolynomial1DEval(%f, chebPolys[%d]) is %f\n", x, i, psPolynomial1DEval(x, chebPolys[i]));
+    }
+    tmp-= (myPoly->coeff[0]/2.0);
+
+
+    return(tmp);
+    */
+}
+
+float psPolynomial1DEval(float x, const psPolynomial1D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psOrdPolynomial1DEval(x, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psChebPolynomial1DEval(x, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psPolynomial1DEvalVector(const psVector *x,
+                                   const psPolynomial1D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    int i;
+
+    PS_CONVERT_VECTOR_F32(x, myX);
+
+    tmp = psVectorAlloc(x->n, PS_TYPE_F32);
+    for (i=0;i<x->n;i++) {
+        tmp->data.F32[i] = psPolynomial1DEval(x->data.F32[i], myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    return(tmp);
+}
+
+
+float p_psOrdPolynomial2DEval(float x, float y, const psPolynomial2D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        ySum = xSum;
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            if (myPoly->mask[loop_x][loop_y] == 0) {
+                polySum += ySum * myPoly->coeff[loop_x][loop_y];
+                ySum *= y;
+            }
+        }
+        xSum *= x;
+    }
+
+    return(polySum);
+}
+
+float p_psChebPolynomial2DEval(float x, float y, const psPolynomial2D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int i = 0;
+    float polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nX;
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            if (myPoly->mask[loop_x][loop_y] == 0) {
+                polySum += myPoly->coeff[loop_x][loop_y] *
+                           psPolynomial1DEval(x, chebPolys[loop_x]) *
+                           psPolynomial1DEval(y, chebPolys[loop_y]);
+            }
+        }
+    }
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+float psPolynomial2DEval(float x, float y, const psPolynomial2D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psOrdPolynomial2DEval(x, y, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psChebPolynomial2DEval(x, y, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+
+psVector *psPolynomial2DEvalVector(const psVector *x,
+                                   const psVector *y,
+                                   const psPolynomial2D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F32(x, myX);
+    PS_CONVERT_VECTOR_F32(y, myY);
+    vecLen=x->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F32);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F32[i] = psPolynomial2DEval(myX->data.F32[i],
+                                              myY->data.F32[i],
+                                              myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F32) {
+        psFree(myY);
+    }
+    return(tmp);
+}
+
+
+
+float p_psOrdPolynomial3DEval(float x, float y, float z, const psPolynomial3D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    float polySum = 0.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+    float zSum = 1.0;
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        ySum = xSum;
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            zSum = ySum;
+            for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                if (myPoly->mask[loop_x][loop_y][loop_z] == 0) {
+                    polySum += zSum * myPoly->coeff[loop_x][loop_y][loop_z];
+                    zSum *= z;
+                }
+            }
+            ySum *= y;
+        }
+        xSum *= x;
+    }
+
+    return(polySum);
+}
+
+float p_psChebPolynomial3DEval(float x, float y, float z, const psPolynomial3D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    int i = 0;
+    float polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nX;
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    if (myPoly->nZ > maxChebyPoly) {
+        maxChebyPoly = myPoly->nZ;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                if (myPoly->mask[loop_x][loop_y][loop_z] == 0) {
+                    polySum += myPoly->coeff[loop_x][loop_y][loop_z] *
+                               psPolynomial1DEval(x, chebPolys[loop_x]) *
+                               psPolynomial1DEval(y, chebPolys[loop_y]) *
+                               psPolynomial1DEval(z, chebPolys[loop_z]);
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+float psPolynomial3DEval(float x, float y, float z, const psPolynomial3D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psOrdPolynomial3DEval(x, y, z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psChebPolynomial3DEval(x, y, z, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psPolynomial3DEvalVector(const psVector *x,
+                                   const psVector *y,
+                                   const psVector *z,
+                                   const psPolynomial3D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F32(x, myX);
+    PS_CONVERT_VECTOR_F32(y, myY);
+    PS_CONVERT_VECTOR_F32(z, myZ);
+    vecLen=x->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+    if (z->n < vecLen) {
+        vecLen = z->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F32);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F32[i] = psPolynomial3DEval(myX->data.F32[i],
+                                              myY->data.F32[i],
+                                              myZ->data.F32[i],
+                                              myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F32) {
+        psFree(myY);
+    }
+    if (z->type.type != PS_TYPE_F32) {
+        psFree(myZ);
+    }
+    return(tmp);
+}
+
+
+
+
+
+
+float p_psOrdPolynomial4DEval(float w, float x, float y, float z, const psPolynomial4D* myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    float polySum = 0.0;
+    float wSum = 1.0;
+    float xSum = 1.0;
+    float ySum = 1.0;
+    float zSum = 1.0;
+
+    for (loop_w = 0; loop_w < myPoly->nW; loop_w++) {
+        xSum = wSum;
+        for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+            ySum = xSum;
+            for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+                zSum = ySum;
+                for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                    if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) {
+                        polySum += zSum * myPoly->coeff[loop_w][loop_x][loop_y][loop_z];
+                        zSum *= z;
+                    }
+                }
+                ySum *= y;
+            }
+            xSum *= x;
+        }
+        wSum *= w;
+    }
+
+    return(polySum);
+}
+
+float p_psChebPolynomial4DEval(float w, float x, float y, float z, const psPolynomial4D* myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    int i = 0;
+    float polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nW;
+    if (myPoly->nX > maxChebyPoly) {
+        maxChebyPoly = myPoly->nX;
+    }
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    if (myPoly->nZ > maxChebyPoly) {
+        maxChebyPoly = myPoly->nZ;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_w = 0; loop_w < myPoly->nW; loop_w++) {
+        for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+            for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+                for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                    if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) {
+                        polySum += myPoly->coeff[loop_w][loop_x][loop_y][loop_z] *
+                                   psPolynomial1DEval(w, chebPolys[loop_w]) *
+                                   psPolynomial1DEval(x, chebPolys[loop_x]) *
+                                   psPolynomial1DEval(y, chebPolys[loop_y]) *
+                                   psPolynomial1DEval(z, chebPolys[loop_z]);
+                    }
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+float psPolynomial4DEval(float w, float x, float y, float z, const psPolynomial4D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psOrdPolynomial4DEval(w,x,y,z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psChebPolynomial4DEval(w,x,y,z, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psPolynomial4DEvalVector(const psVector *w,
+                                   const psVector *x,
+                                   const psVector *y,
+                                   const psVector *z,
+                                   const psPolynomial4D *myPoly)
+{
+    psVector *tmp;
+    psVector *myW;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F32(w, myW);
+    PS_CONVERT_VECTOR_F32(x, myX);
+    PS_CONVERT_VECTOR_F32(y, myY);
+    PS_CONVERT_VECTOR_F32(z, myZ);
+    vecLen=w->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+    if (x->n < vecLen) {
+        vecLen = x->n;
+    }
+    if (z->n < vecLen) {
+        vecLen = z->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F32);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F32[i] = psPolynomial4DEval(myW->data.F32[i],
+                                              myX->data.F32[i],
+                                              myY->data.F32[i],
+                                              myZ->data.F32[i],
+                                              myPoly);
+    }
+
+    if (w->type.type != PS_TYPE_F32) {
+        psFree(myW);
+    }
+    if (x->type.type != PS_TYPE_F32) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F32) {
+        psFree(myY);
+    }
+    if (z->type.type != PS_TYPE_F32) {
+        psFree(myZ);
+    }
+    return(tmp);
+}
+
+
+
+
+
+psDPolynomial1D* psDPolynomial1DAlloc(int n,
+                                      psPolynomialType type)
+{
+    int i = 0;
+    psDPolynomial1D* newPoly = NULL;
+
+    newPoly = (psDPolynomial1D* ) psAlloc(sizeof(psDPolynomial1D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) dPolynomial1DFree);
+
+    newPoly->type = type;
+    newPoly->n = n;
+    newPoly->coeff = (double *)psAlloc(n * sizeof(double));
+    newPoly->coeffErr = (double *)psAlloc(n * sizeof(double));
+    newPoly->mask = (char *)psAlloc(n * sizeof(char));
+    for (i = 0; i < n; i++) {
+        newPoly->coeff[i] = 0.0;
+        newPoly->coeffErr[i] = 0.0;
+        newPoly->mask[i] = 0;
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial2D* psDPolynomial2DAlloc(int nX, int nY,
+                                      psPolynomialType type)
+{
+    int x = 0;
+    int y = 0;
+    psDPolynomial2D* newPoly = NULL;
+
+    newPoly = (psDPolynomial2D* ) psAlloc(sizeof(psDPolynomial2D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) dPolynomial2DFree);
+
+    newPoly->type = type;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+
+    newPoly->coeff = (double **)psAlloc(nX * sizeof(double *));
+    newPoly->coeffErr = (double **)psAlloc(nX * sizeof(double *));
+    newPoly->mask = (char **)psAlloc(nX * sizeof(char *));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (double *)psAlloc(nY * sizeof(double));
+        newPoly->coeffErr[x] = (double *)psAlloc(nY * sizeof(double));
+        newPoly->mask[x] = (char *)psAlloc(nY * sizeof(char));
+    }
+    for (x = 0; x < nX; x++) {
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = 0.0;
+            newPoly->coeffErr[x][y] = 0.0;
+            newPoly->mask[x][y] = 0;
+        }
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial3D* psDPolynomial3DAlloc(int nX, int nY, int nZ,
+                                      psPolynomialType type)
+{
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psDPolynomial3D* newPoly = NULL;
+
+    newPoly = (psDPolynomial3D* ) psAlloc(sizeof(psDPolynomial3D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) dPolynomial3DFree);
+
+    newPoly->type = type;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff = (double ***)psAlloc(nX * sizeof(double **));
+    newPoly->coeffErr = (double ***)psAlloc(nX * sizeof(double **));
+    newPoly->mask = (char ***)psAlloc(nX * sizeof(char **));
+    for (x = 0; x < nX; x++) {
+        newPoly->coeff[x] = (double **)psAlloc(nY * sizeof(double *));
+        newPoly->coeffErr[x] = (double **)psAlloc(nY * sizeof(double *));
+        newPoly->mask[x] = (char **)psAlloc(nY * sizeof(char *));
+        for (y = 0; y < nY; y++) {
+            newPoly->coeff[x][y] = (double *)psAlloc(nZ * sizeof(double));
+            newPoly->coeffErr[x][y] = (double *)psAlloc(nZ * sizeof(double));
+            newPoly->mask[x][y] = (char *)psAlloc(nZ * sizeof(char));
+        }
+    }
+    for (x = 0; x < nX; x++) {
+        for (y = 0; y < nY; y++) {
+            for (z = 0; z < nZ; z++) {
+                newPoly->coeff[x][y][z] = 0.0;
+                newPoly->coeffErr[x][y][z] = 0.0;
+                newPoly->mask[x][y][z] = 0;
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+psDPolynomial4D* psDPolynomial4DAlloc(int nW, int nX, int nY, int nZ,
+                                      psPolynomialType type)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+    int z = 0;
+    psDPolynomial4D* newPoly = NULL;
+
+    newPoly = (psDPolynomial4D* ) psAlloc(sizeof(psDPolynomial4D));
+    p_psMemSetDeallocator(newPoly, (psFreeFcn) dPolynomial4DFree);
+
+    newPoly->type = type;
+    newPoly->nW = nW;
+    newPoly->nX = nX;
+    newPoly->nY = nY;
+    newPoly->nZ = nZ;
+
+    newPoly->coeff = (double ****)psAlloc(nW * sizeof(double ***));
+    newPoly->coeffErr = (double ****)psAlloc(nW * sizeof(double ***));
+    newPoly->mask = (char ****)psAlloc(nW * sizeof(char ***));
+    for (w = 0; w < nW; w++) {
+        newPoly->coeff[w] = (double ***)psAlloc(nX * sizeof(double **));
+        newPoly->coeffErr[w] = (double ***)psAlloc(nX * sizeof(double **));
+        newPoly->mask[w] = (char ***)psAlloc(nX * sizeof(char **));
+        for (x = 0; x < nX; x++) {
+            newPoly->coeff[w][x] = (double **)psAlloc(nY * sizeof(double *));
+            newPoly->coeffErr[w][x] = (double **)psAlloc(nY * sizeof(double *));
+            newPoly->mask[w][x] = (char **)psAlloc(nY * sizeof(char *));
+            for (y = 0; y < nY; y++) {
+                newPoly->coeff[w][x][y] = (double *)psAlloc(nZ * sizeof(double));
+                newPoly->coeffErr[w][x][y] = (double *)psAlloc(nZ * sizeof(double));
+                newPoly->mask[w][x][y] = (char *)psAlloc(nZ * sizeof(char));
+            }
+        }
+    }
+    for (w = 0; w < nW; w++) {
+        for (x = 0; x < nX; x++) {
+            for (y = 0; y < nY; y++) {
+                for (z = 0; z < nZ; z++) {
+                    newPoly->coeff[w][x][y][z] = 0.0;
+                    newPoly->coeffErr[w][x][y][z] = 0.0;
+                    newPoly->mask[w][x][y][z] = 0;
+                }
+            }
+        }
+    }
+
+    return(newPoly);
+}
+
+static void dPolynomial1DFree(psDPolynomial1D* myPoly)
+{
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void dPolynomial2DFree(psDPolynomial2D* myPoly)
+{
+    int x = 0;
+
+    for (x = 0; x < myPoly->nX; x++) {
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void dPolynomial3DFree(psDPolynomial3D* myPoly)
+{
+    int x = 0;
+    int y = 0;
+
+    for (x = 0; x < myPoly->nX; x++) {
+        for (y = 0; y < myPoly->nY; y++) {
+            psFree(myPoly->coeff[x][y]);
+            psFree(myPoly->coeffErr[x][y]);
+            psFree(myPoly->mask[x][y]);
+        }
+        psFree(myPoly->coeff[x]);
+        psFree(myPoly->coeffErr[x]);
+        psFree(myPoly->mask[x]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+static void dPolynomial4DFree(psDPolynomial4D* myPoly)
+{
+    int w = 0;
+    int x = 0;
+    int y = 0;
+
+    for (w = 0; w < myPoly->nW; w++) {
+        for (x = 0; x < myPoly->nX; x++) {
+            for (y = 0; y < myPoly->nY; y++) {
+                psFree(myPoly->coeff[w][x][y]);
+                psFree(myPoly->coeffErr[w][x][y]);
+                psFree(myPoly->mask[w][x][y]);
+            }
+            psFree(myPoly->coeff[w][x]);
+            psFree(myPoly->coeffErr[w][x]);
+            psFree(myPoly->mask[w][x]);
+        }
+        psFree(myPoly->coeff[w]);
+        psFree(myPoly->coeffErr[w]);
+        psFree(myPoly->mask[w]);
+    }
+
+    psFree(myPoly->coeff);
+    psFree(myPoly->coeffErr);
+    psFree(myPoly->mask);
+}
+
+/*****************************************************************************
+    Polynomial coefficients will be accessed in [w][x][y][z] fashion.
+ *****************************************************************************/
+double p_psDOrdPolynomial1DEval(double x, const psDPolynomial1D* myPoly)
+{
+    int loop_x = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+
+    // NOTE: Do we want to flag this case?
+    if (myPoly->n == 0) {
+        return(1.0);
+    }
+
+    for (loop_x = 0; loop_x < myPoly->n; loop_x++) {
+        if (myPoly->mask[loop_x] == 0) {
+            polySum += xSum * myPoly->coeff[loop_x];
+            xSum *= x;
+        }
+    }
+
+    return(polySum);
+}
+
+// XXX: You can do this without having to psAlloc() vector d.
+// XXX: How does the mask vector effect Crenshaw's formula?
+double p_psDChebPolynomial1DEval(double x, const psDPolynomial1D* myPoly)
+{
+    psVector *d;
+    int n;
+    int i;
+    double tmp;
+
+    n = myPoly->n;
+    d = psVectorAlloc(n, PS_TYPE_F64);
+    d->data.F64[n-1] = myPoly->coeff[n-1];
+    d->data.F64[n-2] = (2.0 * x * d->data.F64[n-1]) + myPoly->coeff[n-2];
+    for (i=n-3;i>=1;i--) {
+        d->data.F64[i] = (2.0 * x * d->data.F64[i+1]) -
+                         (d->data.F64[i+2]) +
+                         (myPoly->coeff[i]);
+    }
+
+    tmp = (x * d->data.F64[1]) -
+          (d->data.F64[2]) +
+          (0.5 * myPoly->coeff[0]);
+
+    psFree(d);
+    return(tmp);
+}
+
+double psDPolynomial1DEval(double x, const psDPolynomial1D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psDOrdPolynomial1DEval(x, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psDChebPolynomial1DEval(x, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psDPolynomial1DEvalVector(const psVector *x,
+                                    const psDPolynomial1D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    int i;
+
+    PS_CONVERT_VECTOR_F64(x, myX);
+
+    tmp = psVectorAlloc(x->n, PS_TYPE_F64);
+    for (i=0;i<x->n;i++) {
+        tmp->data.F64[i] = psDPolynomial1DEval(x->data.F64[i], myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    return(tmp);
+}
+
+
+
+double p_psDOrdPolynomial2DEval(double x, double y, const psDPolynomial2D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        ySum = xSum;
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            if (myPoly->mask[loop_x][loop_y] == 0) {
+                polySum += ySum * myPoly->coeff[loop_x][loop_y];
+                ySum *= y;
+            }
+        }
+        xSum *= x;
+    }
+
+    return(polySum);
+}
+
+double p_psDChebPolynomial2DEval(double x, double y, const psDPolynomial2D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int i = 0;
+    double polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nX;
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            if (myPoly->mask[loop_x][loop_y] == 0) {
+                polySum += myPoly->coeff[loop_x][loop_y] *
+                           psPolynomial1DEval(x, chebPolys[loop_x]) *
+                           psPolynomial1DEval(y, chebPolys[loop_y]);
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+double psDPolynomial2DEval(double x, double y, const psDPolynomial2D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psDOrdPolynomial2DEval(x, y, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psDChebPolynomial2DEval(x, y, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psDPolynomial2DEvalVector(const psVector *x,
+                                    const psVector *y,
+                                    const psDPolynomial2D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F64(x, myX);
+    PS_CONVERT_VECTOR_F64(y, myY);
+    vecLen=x->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F64);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F64[i] = psDPolynomial2DEval(myX->data.F64[i],
+                                               myY->data.F64[i],
+                                               myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F64) {
+        psFree(myY);
+    }
+    return(tmp);
+}
+
+
+
+double p_psDOrdPolynomial3DEval(double x, double y, double z, const psDPolynomial3D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    double polySum = 0.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+    double zSum = 1.0;
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        ySum = xSum;
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            zSum = ySum;
+            for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                if (myPoly->mask[loop_x][loop_y][loop_z] == 0) {
+                    polySum += zSum * myPoly->coeff[loop_x][loop_y][loop_z];
+                    zSum *= z;
+                }
+            }
+            ySum *= y;
+        }
+        xSum *= x;
+    }
+
+    return(polySum);
+}
+
+double p_psDChebPolynomial3DEval(double x, double y, double z, const psDPolynomial3D* myPoly)
+{
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    int i = 0;
+    double polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nX;
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    if (myPoly->nZ > maxChebyPoly) {
+        maxChebyPoly = myPoly->nZ;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+        for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+            for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                if (myPoly->mask[loop_x][loop_y][loop_z] == 0) {
+                    polySum += myPoly->coeff[loop_x][loop_y][loop_z] *
+                               psPolynomial1DEval(x, chebPolys[loop_x]) *
+                               psPolynomial1DEval(y, chebPolys[loop_y]) *
+                               psPolynomial1DEval(z, chebPolys[loop_z]);
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+double psDPolynomial3DEval(double x, double y, double z, const psDPolynomial3D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psDOrdPolynomial3DEval(x, y, z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psDChebPolynomial3DEval(x, y, z, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psDPolynomial3DEvalVector(const psVector *x,
+                                    const psVector *y,
+                                    const psVector *z,
+                                    const psDPolynomial3D *myPoly)
+{
+    psVector *tmp;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F64(x, myX);
+    PS_CONVERT_VECTOR_F64(y, myY);
+    PS_CONVERT_VECTOR_F64(z, myZ);
+    vecLen=x->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+    if (z->n < vecLen) {
+        vecLen = z->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F64);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F64[i] = psDPolynomial3DEval(myX->data.F64[i],
+                                               myY->data.F64[i],
+                                               myZ->data.F64[i],
+                                               myPoly);
+    }
+
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F64) {
+        psFree(myY);
+    }
+    if (z->type.type != PS_TYPE_F64) {
+        psFree(myZ);
+    }
+    return(tmp);
+}
+
+
+
+
+
+
+
+
+double p_psDOrdPolynomial4DEval(double w, double x, double y, double z, const psDPolynomial4D* myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    double polySum = 0.0;
+    double wSum = 1.0;
+    double xSum = 1.0;
+    double ySum = 1.0;
+    double zSum = 1.0;
+
+    for (loop_w = 0; loop_w < myPoly->nW; loop_w++) {
+        xSum = wSum;
+        for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+            ySum = xSum;
+            for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+                zSum = ySum;
+                for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                    if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) {
+                        polySum += zSum * myPoly->coeff[loop_w][loop_x][loop_y][loop_z];
+                        zSum *= z;
+                    }
+                }
+                ySum *= y;
+            }
+            xSum *= x;
+        }
+        wSum *= w;
+    }
+
+    return(polySum);
+}
+
+double p_psDChebPolynomial4DEval(double w, double x, double y, double z, const psDPolynomial4D* myPoly)
+{
+    int loop_w = 0;
+    int loop_x = 0;
+    int loop_y = 0;
+    int loop_z = 0;
+    int i = 0;
+    double polySum = 0.0;
+    psPolynomial1D* *chebPolys = NULL;
+    int maxChebyPoly = 0;
+
+    // Determine how many Chebyshev polynomials
+    // are needed, then create them.
+    maxChebyPoly = myPoly->nW;
+    if (myPoly->nX > maxChebyPoly) {
+        maxChebyPoly = myPoly->nX;
+    }
+    if (myPoly->nY > maxChebyPoly) {
+        maxChebyPoly = myPoly->nY;
+    }
+    if (myPoly->nZ > maxChebyPoly) {
+        maxChebyPoly = myPoly->nZ;
+    }
+    chebPolys = CreateChebyshevPolys(maxChebyPoly);
+
+    for (loop_w = 0; loop_w < myPoly->nW; loop_w++) {
+        for (loop_x = 0; loop_x < myPoly->nX; loop_x++) {
+            for (loop_y = 0; loop_y < myPoly->nY; loop_y++) {
+                for (loop_z = 0; loop_z < myPoly->nZ; loop_z++) {
+                    if (myPoly->mask[loop_w][loop_x][loop_y][loop_z] == 0) {
+                        polySum += myPoly->coeff[loop_w][loop_x][loop_y][loop_z] *
+                                   psPolynomial1DEval(w, chebPolys[loop_w]) *
+                                   psPolynomial1DEval(x, chebPolys[loop_x]) *
+                                   psPolynomial1DEval(y, chebPolys[loop_y]) *
+                                   psPolynomial1DEval(z, chebPolys[loop_z]);
+                    }
+                }
+            }
+        }
+    }
+
+    for (i=0;i<maxChebyPoly;i++) {
+        psFree(chebPolys[i]);
+    }
+    psFree(chebPolys);
+    return(polySum);
+}
+
+double psDPolynomial4DEval(double w, double x, double y, double z, const psDPolynomial4D* myPoly)
+{
+    if (myPoly->type == PS_POLYNOMIAL_ORD) {
+        return(p_psDOrdPolynomial4DEval(w,x,y,z, myPoly));
+    } else if (myPoly->type == PS_POLYNOMIAL_CHEB) {
+        return(p_psDChebPolynomial4DEval(w,x,y,z, myPoly));
+    } else {
+        psAbort(__func__, "Unknown polynomial type 0x%x\n", myPoly->type);
+    }
+    return(0.0);
+}
+
+psVector *psDPolynomial4DEvalVector(const psVector *w,
+                                    const psVector *x,
+                                    const psVector *y,
+                                    const psVector *z,
+                                    const psDPolynomial4D *myPoly)
+{
+    psVector *tmp;
+    psVector *myW;
+    psVector *myX;
+    psVector *myY;
+    psVector *myZ;
+    int i;
+    int vecLen=x->n;
+
+    PS_CONVERT_VECTOR_F64(w, myW);
+    PS_CONVERT_VECTOR_F64(x, myX);
+    PS_CONVERT_VECTOR_F64(y, myY);
+    PS_CONVERT_VECTOR_F64(z, myZ);
+    vecLen=w->n;
+    if (y->n < vecLen) {
+        vecLen = y->n;
+    }
+    if (x->n < vecLen) {
+        vecLen = x->n;
+    }
+    if (z->n < vecLen) {
+        vecLen = z->n;
+    }
+
+    tmp = psVectorAlloc(vecLen, PS_TYPE_F64);
+    for (i=0;i<vecLen;i++) {
+        tmp->data.F64[i] = psDPolynomial4DEval(myW->data.F64[i],
+                                               myX->data.F64[i],
+                                               myY->data.F64[i],
+                                               myZ->data.F64[i],
+                                               myPoly);
+    }
+
+    if (w->type.type != PS_TYPE_F64) {
+        psFree(myW);
+    }
+    if (x->type.type != PS_TYPE_F64) {
+        psFree(myX);
+    }
+    if (y->type.type != PS_TYPE_F64) {
+        psFree(myY);
+    }
+    if (z->type.type != PS_TYPE_F64) {
+        psFree(myZ);
+    }
+    return(tmp);
+}
+
+
+
+
+//typedef struct {
+//    int n;
+//    psPolynomial1D **spline;
+//    float *p_psDeriv2;
+//    float *domains;
+//} psSpline1D;
+
+/*****************************************************************************
+    NOTE: "n" specifies the number of spline polynomials.  Therefore, there
+    must exist n+1 points in "domains".
+ 
+XXX: Ensure that domain[i+1] != domain[i]
+ *****************************************************************************/
+psSpline1D *psSpline1DAlloc(int numSplines,
+                            int order,
+                            float min,
+                            float max)
+{
+    psSpline1D *tmp = NULL;
+    int i;
+    float tmpDomain;
+    float width;
+
+    if (fabs(max-min) < FLT_EPSILON) {
+        psLogMsg(__func__, PS_LOG_WARN, "min and max are the same.\n");
+        return(NULL);
+    }
+
+    tmp = (psSpline1D *) psAlloc(sizeof(psSpline1D));
+    tmp->n = numSplines;
+
+    tmp->spline = (psPolynomial1D **) psAlloc(numSplines * sizeof(psPolynomial1D *));
+    for (i=0;i<numSplines;i++) {
+        (tmp->spline)[i] = psPolynomial1DAlloc(order+1, PS_POLYNOMIAL_ORD);
+    }
+
+    // This should be set by the psVectorFitSpline1D()
+    tmp->p_psDeriv2 = NULL;
+
+    tmp->domains = (float *) psAlloc((numSplines+1) * sizeof(float));
+    width = (max - min) / ((float) numSplines);
+
+    (tmp->domains)[0] = min;
+    tmpDomain = min+width;
+    for (i=1;i<numSplines+1;i++) {
+        (tmp->domains)[i] = tmpDomain;
+        tmpDomain+= width;
+    }
+    (tmp->domains)[numSplines] = max;
+
+    return(tmp);
+}
+
+// XXX: Have Robert put the dealocator in the memory file.
+int p_psSpline1DFree(psSpline1D *tmpSpline)
+{
+    int i;
+
+    if (tmpSpline == NULL) {
+        return(0);
+    }
+
+    if (tmpSpline->spline != NULL) {
+        for (i=0;i<tmpSpline->n;i++) {
+            psFree((tmpSpline->spline)[i]);
+        }
+        psFree(tmpSpline->spline);
+    }
+
+    if (tmpSpline->p_psDeriv2 != NULL) {
+        psFree(tmpSpline->p_psDeriv2);
+    }
+    psFree(tmpSpline->domains);
+    psFree(tmpSpline);
+
+    return(0);
+}
+
+/*****************************************************************************
+ *****************************************************************************/
+psSpline1D *psSpline1DAllocGeneric(const psVector *bounds,
+                                   int order)
+{
+    psSpline1D *tmp = NULL;
+    int i;
+    int numSplines;
+
+    tmp = (psSpline1D *) psAlloc(sizeof(psSpline1D));
+
+    numSplines = bounds->n - 1;
+    tmp->n = numSplines;
+
+    tmp->spline = (psPolynomial1D **) psAlloc(numSplines * sizeof(psPolynomial1D *));
+    for (i=0;i<numSplines;i++) {
+        (tmp->spline)[i] = psPolynomial1DAlloc(order+1, PS_POLYNOMIAL_ORD);
+    }
+
+    tmp->domains = (float *) psAlloc((bounds->n) * sizeof(float));
+
+    for (i=0;i<bounds->n;i++) {
+        (tmp->domains)[i] = bounds->data.F32[i];
+        if (i<(bounds->n-1)) {
+            if (FLT_EPSILON < fabs(bounds->data.F32[i+1]-bounds->data.F32[i])) {
+                // XXX: psErrorMsg(data points must be distinct)
+            }
+        }
+    }
+
+    return(tmp);
+}
+
+/*****************************************************************************
+p_psVectorBinDisectF32(): This is a private function which takes as input a
+vector of floating point data as well as a single floating point values.
+The input vector values are assumed to be non-decreasing (v[i-1] <= v[j] for
+all j>=i).  This routine does a binary disection of the vector and returns
+"i" such that (v[i] <= x <= v[i+1).  If x lies outside the range of v[],
+then this routine prints a warning message and returns (-2 or -1).
+ 
+XXX: Macro this for a few different types.
+ 
+XXX: name since we don't take psVectors as input.
+ *****************************************************************************/
+int p_psVectorBinDisectF32(float *bins,
+                           int numBins,
+                           float x)
+{
+    int min;
+    int max;
+    int mid;
+
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectF32", 4,
+            "---- Calling p_psVectorBinDisectF32(%f)\n", x);
+
+    if (x < bins[0]) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "p_psVectorBinDisectF32(): ordinate %f is outside vector range (%f - %f).",
+                 x, bins[0], bins[numBins-1]);
+        return(-2);
+    }
+
+    if (x > bins[numBins-1]) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "p_psVectorBinDisectF32(): ordinate %f is outside vector range (%f - %f).",
+                 x, bins[0], bins[numBins-1]);
+        return(-1);
+    }
+
+    min = 0;
+    max = numBins-2;
+    mid = ((max+1)-min)/2;
+
+    while (min != max) {
+        psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectF32", 4,
+                "(min, mid, max) is (%d, %d, %d): (x, bins) is (%f, %f)\n",
+                min, mid, max, x, bins[mid]);
+
+        if (x == bins[mid]) {
+            psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectF32", 4,
+                    "---- Exiting p_psVectorBinDisectF32(): bin %d\n", mid);
+            return(mid);
+        } else if (x < bins[mid]) {
+            max = mid-1;
+        } else {
+            min = mid;
+        }
+        mid = ((max+1)+min)/2;
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectF32", 4,
+            "---- Exiting p_psVectorBinDisectF32(): bin %d\n", min);
+    return(min);
+}
+
+/*****************************************************************************
+p_psVectorBinDisectS32(): integer version of above.
+ *****************************************************************************/
+int p_psVectorBinDisectS32(int *bins,
+                           int numBins,
+                           int x)
+{
+    int min;
+    int max;
+    int mid;
+
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectS32", 4,
+            "---- Calling p_psVectorBinDisectS32(%f)\n", x);
+
+    if ((x < bins[0]) ||
+            (x > bins[numBins-1])) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "p_psVectorBinDisectS32(): ordinate %f is outside vector range (%f - %f).",
+                 x, bins[0], bins[numBins-1]);
+        return(-1);
+    }
+
+    min = 0;
+    max = numBins-2;
+    mid = ((max+1)-min)/2;
+
+    while (min != max) {
+        psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectS32", 4,
+                "(min, mid, max) is (%d, %d, %d): (x, bins) is (%f, %f)\n",
+                min, mid, max, x, bins[mid]);
+
+        if (x == bins[mid]) {
+            psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectS32", 4,
+                    "---- Exiting p_psVectorBinDisectS32(): bin %d\n", min);
+            return(min);
+        } else if (x < bins[mid]) {
+            max = mid-1;
+        } else {
+            min = mid;
+        }
+        mid = ((max+1)+min)/2;
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorBinDisectS32", 4,
+            "---- Exiting p_psVectorBinDisectS32(): bin %d\n", min);
+    return(min);
+}
+
+/*****************************************************************************
+p_psVectorBinDisect(): A wrapper to the above p_psVectorBinDisect().
+ *****************************************************************************/
+int p_psVectorBinDisect(psVector *bins,
+                        psScalar *x)
+{
+    if (x->type.type != bins->type.type) {
+        psError(__func__, "x->type.type != bins->type.type");
+        return(-2);
+    }
+
+    if (x->type.type == PS_TYPE_S32) {
+        return(p_psVectorBinDisectS32(bins->data.S32, bins->n, x->data.S32));
+    } else if (x->type.type == PS_TYPE_F32) {
+        return(p_psVectorBinDisectF32(bins->data.F32, bins->n, x->data.F32));
+    } else {
+        psError(__func__, "Unallowable data type.");
+        return(-2);
+    }
+    return(-1);
+}
+
+/*****************************************************************************
+p_psInterpolate1D(): This routine will take as input n-element floating
+point arrays domain and range, and the x value, assumed to lie with the
+domain vector.  It produces as output the (n-1)-order LaGrange interpolated
+value of x.
+ 
+XXX: do we error check for non-distinct domain values?
+ *****************************************************************************/
+float p_ps1DFullInterpolateF32(float *domain,
+                               float *range,
+                               int n,
+                               float x)
+{
+    int i;
+    int m;
+    static psVector *p = NULL;
+    p = psVectorRecycle(p, n, PS_TYPE_F32);
+    p_psMemSetPersistent(p, true);
+    p_psMemSetPersistent(p->data.F32, true);
+    /*
+        psVector *p = psVectorAlloc(n, PS_TYPE_F32);
+        float tmp;
+    */
+
+    psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 4,
+            "---- p_ps1DFullInterpolateF32() begin (%d-order at x=%f) (%d data points)----\n", n-1, x, n);
+
+    for (i=0;i<n;i++) {
+        psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 6,
+                "domain/range is (%f %f)\n", domain[i], range[i]);
+    }
+
+    for (i=0;i<n;i++) {
+        p->data.F32[i] = range[i];
+        psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 6,
+                "p->data.F32[%d] is %f\n", i, p->data.F32[i]);
+
+    }
+
+    // From NR, during each iteration of the m loop, we are computing the
+    // p_{i ... i+m} terms.
+    for (m=1;m<n;m++) {
+        for (i=0;i<n-m;i++) {
+            // From NR: we are computing P_{i ... i+m}
+            p->data.F32[i] = (((x-domain[i+m]) * p->data.F32[i]) +
+                              ((domain[i]-x) * p->data.F32[i+1])) /
+                             (domain[i] - domain[i+m]);
+            //printf("((%f-%f * %f) + (%f-%f * %f)) / (%f - %f)\n", x, domain[i+m], p->data.F32[i], domain[i], x, p->data.F32[i+1], domain[i], domain[i+m]);
+            psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 6,
+                    "p->data.F32[%d] is %f\n", i, p->data.F32[i]);
+        }
+    }
+    psTrace(".psLib.dataManip.psFunctions.p_ps1DFullInterpolateF32", 4,
+            "---- p_ps1DFullInterpolateF32() end ----\n");
+
+    /*
+        tmp = p->data.F32[0];
+        psFree(p);
+        return(tmp);
+    */
+    return(p->data.F32[0]);
+}
+
+
+/*****************************************************************************
+p_ps1DInterpolateF32(): this is the base 1-D flat memory routine to perform
+LaGrange interpolation.
+ *****************************************************************************/
+float p_ps1DInterpolateF32(float *domain,
+                           float *range,
+                           int n,
+                           int order,
+                           float x)
+{
+    int binNum;
+    int numIntPoints = order+1;
+    int origin;
+
+    psTrace(".psLib.dataManip.psFunctions.p_ps1DInterpolateF32", 4,
+            "---- p_ps1DInterpolateF32() begin ----\n");
+
+    binNum = p_psVectorBinDisectF32(domain, n, x);
+
+    if (0 == numIntPoints%2) {
+        origin = binNum - ((numIntPoints/2) - 1);
+    } else {
+        origin = binNum - (numIntPoints/2);
+        if ((x-domain[binNum]) > (domain[binNum+1]-x)) {
+            // x is closer to binNum+1.
+            origin = 1 + (binNum - (numIntPoints/2));
+        }
+    }
+    if (origin < 0) {
+        origin = 0;
+    }
+    if ((origin + numIntPoints) > n) {
+        origin = n - numIntPoints;
+    }
+
+    psTrace(".psLib.dataManip.psFunctions.p_ps1DInterpolateF32", 4,
+            "---- p_ps1DInterpolateF32() end ----\n");
+    return(p_ps1DFullInterpolateF32(&domain[origin], &range[origin], order+1, x));
+}
+
+/*****************************************************************************
+p_psVectorInterpolate(): This routine will take as input psVectors domain and
+range, and the x value, assumed to lie with the domain vector.  It produces
+as output the LaGrange interpolated value of a polynomial of the specified
+order around the point x.
+ 
+XXX: This stuff does not currently work with a mask.
+ 
+XXX: nobody asked for us to generate this routine.
+ 
+XXX: add another psScalar argument for the result.
+ 
+XXX: The VectorCopy routines seg fault when I declare range32 as static.
+ *****************************************************************************/
+psScalar *p_psVectorInterpolate(psVector *domain,
+                                psVector *range,
+                                int order,
+                                psScalar *x)
+{
+    psVector *range32 = NULL;
+    psVector *domain32 = NULL;
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+            "---- p_psVectorInterpolate() begin ----\n");
+
+    if ((domain->type.type != range->type.type) ||
+            (domain->type.type != x->type.type)) {
+        // XXX psError
+        printf("p_psVectorInterpolate(): domain->type.type != range->type.type != x->type.type\n");
+        printf("%d %d %d\n", domain->type.type, range->type.type, x->type.type);
+        exit(1);
+    }
+    if (domain->n != range->n) {
+        // XXX psError
+        printf("domain->n != range->n\n");
+        exit(1);
+    }
+    if (order > (domain->n - 1)) {
+        // XXX psError: not enough data points for order-order interpolation.
+        printf("not enough data points for order-order interpolation.\n");
+        exit(1);
+    }
+
+    if (x->type.type == PS_TYPE_F32) {
+        psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+                "---- p_psVectorInterpolate() end ----\n");
+        return(psScalarAlloc(p_ps1DInterpolateF32(domain->data.F32,
+                             range->data.F32,
+                             domain->n,
+                             order,
+                             x->data.F32), PS_TYPE_F32));
+    } else if (x->type.type == PS_TYPE_F64) {
+        // XXX: use recycled vectors here.
+        range32 = psVectorCopy(range32, range, PS_TYPE_F32);
+        domain32 = psVectorCopy(domain32, domain, PS_TYPE_F32);
+
+        psScalar *tmpScalar = psScalarAlloc((double)
+                                            p_ps1DInterpolateF32(domain32->data.F32,
+                                                                 range32->data.F32,
+                                                                 domain32->n,
+                                                                 order,
+                                                                 (float) x->data.F64), PS_TYPE_F64);
+        psFree(range32);
+        psFree(domain32);
+
+        psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+                "---- p_psVectorInterpolate() end ----\n");
+        // XXX: Convert data type to F64?
+        return(tmpScalar);
+
+    } else {
+        // XXX psError: type not supported
+        printf("XXX psError: type not supported\n");
+    }
+
+    printf("return(NULL)\n");
+    psTrace(".psLib.dataManip.psFunctions.p_psVectorInterpolate", 4,
+            "---- p_psVectorInterpolate() end ----\n");
+    return(NULL);
+}
+
+
+/*****************************************************************************
+psSpline1DEval(): this routine takes an existing spline of arbitrary order
+and an independent x value.  Each determines which spline that x corresponds
+to by doing a bracket disection on the domains of the spline data structure
+(p_psVectorBinDisectF32()).  Then it evaluates the spline at that x location
+by a call to the 1D polynomial functions.
+ 
+XXX: The spline eval functions require input and output to be F32.  however
+     the spline fit functions require F32 and F64.
+ *****************************************************************************/
+float psSpline1DEval(const psSpline1D *spline,
+                     float x)
+{
+    int binNum;
+    int n;
+
+    n = spline->n;
+    binNum = p_psVectorBinDisectF32(spline->domains, (spline->n)+1, x);
+    if (binNum < 0) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "psSpline1DEval(): x ordinate (%f) is outside the spline range (%f - %f).",
+                 x, (spline->domains)[0],
+                 (spline->domains)[n-1]);
+
+        if (x < (spline->domains)[0]) {
+            return(psPolynomial1DEval(x, spline->spline[0]));
+        } else if (x > (spline->domains)[n-1]) {
+            return(psPolynomial1DEval(x, spline->spline[n-1]));
+        }
+    }
+
+    return(psPolynomial1DEval(x, spline->spline[binNum]));
+}
+
+// XXX: The spline eval functions require input and output to be F32.
+// however the spline fit functions require F32 and F64.
+psVector *psSpline1DEvalVector(const psVector *x,
+                               const psSpline1D *spline)
+{
+    int i;
+    psVector *tmpVector;
+
+    tmpVector = psVectorAlloc(x->n, PS_TYPE_F32);
+    if (x->type.type == PS_TYPE_F32) {
+        for (i=0;i<x->n;i++) {
+            tmpVector->data.F32[i] = psSpline1DEval(spline, x->data.F32[i]);
+        }
+    } else if (x->type.type == PS_TYPE_F64) {
+        for (i=0;i<x->n;i++) {
+            tmpVector->data.F32[i] = psSpline1DEval(spline, (float) x->data.F64[i]);
+        }
+    } else {
+        psError(__func__, "Unknown data type.\n");
+        return(NULL);
+    }
+
+    return(tmpVector);
+}
Index: /branches/rel3/psLib/src/math/psSpline.h
===================================================================
--- /branches/rel3/psLib/src/math/psSpline.h	(revision 2163)
+++ /branches/rel3/psLib/src/math/psSpline.h	(revision 2163)
@@ -0,0 +1,435 @@
+/** @file psFunctions.h
+*  \brief Standard Mathematical Functions.
+*  \ingroup Stats
+*
+*  This file will hold the prototypes for procedures which allocate, free,
+*  and evaluate various polynomials.  Those polynomial structures are also
+*  defined here.
+*
+*  @ingroup Stats
+*
+*  @author Someone at IfA
+*  @author George Gusciora, MHPCC
+*
+*  @version $Revision: 1.30 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-06 00:48:15 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#if !defined(PS_FUNCTIONS_H)
+#define PS_FUNCTIONS_H
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <float.h>
+#include <math.h>
+
+#include "psVector.h"
+#include "psScalar.h"
+
+/** \addtogroup Stats
+ *  \{
+ */
+
+/** Evaluate a non-normalized Gaussian with the given mean and sigma at the
+ *  given coordianate.  
+ *
+ *  Note that this is not a Gaussian deviate.  The evaluated Gaussian is: 
+ *        \f[ exp(-\frac{(x-mean)^2}{2\sigma^2}) \f] 
+ *
+ *  @return float      value on the gaussian curve given the input parameters
+ */
+float psGaussian(
+    float x,                           ///< Value at which to evaluate
+    float mean,                        ///< Mean for the Gaussian
+    float stddev,                      ///< Standard deviation for the Gaussian
+    bool normal                        ///< Indicates whether result should be normalized
+);
+
+/** Produce a vector of random numbers from a Gaussian distribution with
+ *  the specified mean and sigma 
+ *  
+ *  @return psVector*    vector of random numbers
+ *  
+ */
+psVector* psGaussianDev(
+    float mean,                        ///< The mean of the Gaussian
+    float sigma,                       ///< The sigma of the Gaussian
+    int Npts                           ///< The size of the vector
+);
+
+typedef enum {
+    PS_POLYNOMIAL_ORD,                 ///< Ordinary Polynomial
+    PS_POLYNOMIAL_CHEB                 ///< Chebyshev Polynomial
+} psPolynomialType;
+
+/** One-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int n;                             ///< Number of terms
+    float *coeff;                      ///< Coefficients
+    float *coeffErr;                   ///< Error in coefficients
+    char *mask;                        ///< Coefficient mask
+}
+psPolynomial1D;
+
+/** Two-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    float **coeff;                     ///< Coefficients
+    float **coeffErr;                  ///< Error in coefficients
+    char **mask;                       ///< Coefficients mask
+}
+psPolynomial2D;
+
+/** Three-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    int nZ;                            ///< Number of terms in z
+    float ***coeff;                    ///< Coefficients
+    float ***coeffErr;                 ///< Error in coefficients
+    char ***mask;                      ///< Coefficients mask
+}
+psPolynomial3D;
+
+/** Four-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nW;                            ///< Number of terms in w
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    int nZ;                            ///< Number of terms in z
+    float ****coeff;                   ///< Coefficients
+    float ****coeffErr;                ///< Error in coefficients
+    char ****mask;                     ///< Coefficients mask
+}
+psPolynomial4D;
+
+
+/** Allocates a psPolynomial1D structure with n terms
+ *
+ *  @return  psPolynomial1D*    new 1-D polynomial struct
+ */
+psPolynomial1D* psPolynomial1DAlloc(
+    int n,                              ///< Number of terms
+    psPolynomialType type               ///< Polynomial Type
+);
+
+/** Allocates a 2-D polynomial structure
+ *
+ *  @return  psPolynomial2D*    new 2-D polynomial struct
+ */
+psPolynomial2D* psPolynomial2DAlloc(
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Allocates a 3-D polynomial structure
+ *
+ *  @return  psPolynomial3D*    new 3-D polynomial struct
+ */
+psPolynomial3D* psPolynomial3DAlloc(
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    int nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Allocates a 4-D polynomial structure
+ *
+ *  @return  psPolynomial4D*    new 4-D polynomial struct
+ */
+psPolynomial4D* psPolynomial4DAlloc(
+    int nW,                            ///< Number of terms in w
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    int nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Evaluates a 1-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+float psPolynomial1DEval(
+    float x,                           ///< location at which to evaluate
+    const psPolynomial1D* myPoly       ///< Coefficients for the polynomial
+);
+
+/** Evaluates a 2-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+float psPolynomial2DEval(
+    float x,                           ///< x location at which to evaluate
+    float y,                           ///< y location at which to evaluate
+    const psPolynomial2D* myPoly       ///< Coefficients for the polynomial
+);
+
+/** Evaluates a 3-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+float psPolynomial3DEval(
+    float x,                           ///< x location at which to evaluate
+    float y,                           ///< y location at which to evaluate
+    float z,                           ///< z location at which to evaluate
+    const psPolynomial3D* myPoly       ///< Coefficients for the polynomial
+);
+
+/** Evaluates a 4-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+float psPolynomial4DEval(
+    float w,                           ///< w location at which to evaluate
+    float x,                           ///< x location at which to evaluate
+    float y,                           ///< y location at which to evaluate
+    float z,                           ///< z location at which to evaluate
+    const psPolynomial4D* myPoly       ///< Coefficients for the polynomial
+);
+
+psVector *psPolynomial1DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                   const psPolynomial1D *myPoly   ///< Coefficients for the polynomial
+                                  );
+
+psVector *psPolynomial2DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                   const psVector *y,             ///< y locations at which to evaluate
+                                   const psPolynomial2D *myPoly   ///< Coefficients for the polynomial
+                                  );
+
+psVector *psPolynomial3DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                   const psVector *y,             ///< y locations at which to evaluate
+                                   const psVector *z,             ///< z locations at which to evaluate
+                                   const psPolynomial3D *myPoly   ///< Coefficients for the polynomial
+                                  );
+
+psVector *psPolynomial4DEvalVector(const psVector *w,             ///< w locations at which to evaluate
+                                   const psVector *x,             ///< x locations at which to evaluate
+                                   const psVector *y,             ///< y locations at which to evaluate
+                                   const psVector *z,             ///< z locations at which to evaluate
+                                   const psPolynomial4D *myPoly   ///< Coefficients for the polynomial
+                                  );
+
+/*****************************************************************************/
+
+/* Double-precision polynomials, mainly for use in astrometry */
+
+/** Double-precision one-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int n;                             ///< Number of terms
+    double *coeff;                     ///< Coefficients
+    double *coeffErr;                  ///< Error in coefficients
+    char *mask;                        ///< Coefficient mask
+}
+psDPolynomial1D;
+
+/** Double-precision two-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    double **coeff;                    ///< Coefficients
+    double **coeffErr;                 ///< Error in coefficients
+    char **mask;                       ///< Coefficients mask
+}
+psDPolynomial2D;
+
+/** Double-precision three-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    int nZ;                            ///< Number of terms in z
+    double ***coeff;                   ///< Coefficients
+    double ***coeffErr;                ///< Error in coefficients
+    char ***mask;                      ///< Coefficient mask
+}
+psDPolynomial3D;
+
+/** Double-precision four-dimensional polynomial */
+typedef struct
+{
+    psPolynomialType type;             ///< Polynomial type
+    int nW;                            ///< Number of terms in w
+    int nX;                            ///< Number of terms in x
+    int nY;                            ///< Number of terms in y
+    int nZ;                            ///< Number of terms in z
+    double ****coeff;                  ///< Coefficients
+    double ****coeffErr;               ///< Error in coefficients
+    char ****mask;                     ///< Coefficients mask
+}
+psDPolynomial4D;
+
+/** Allocates a double-precision 1-D polynomial structure with n terms
+ *
+ *  @return  psPolynomial1D*    new double-precision 1-D polynomial struct
+ */
+psDPolynomial1D* psDPolynomial1DAlloc(
+    int n,                             ///< Number of terms
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Allocates a double-precision 2-D polynomial structure
+ *
+ *  @return  psPolynomial2D*    new double-precision 2-D polynomial struct
+ */
+psDPolynomial2D* psDPolynomial2DAlloc(
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Allocates a double-precision 3-D polynomial structure
+ *
+ *  @return  psPolynomial3D*    new double-precision 3-D polynomial struct
+ */
+psDPolynomial3D* psDPolynomial3DAlloc(
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    int nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Allocates a double-precision 4-D polynomial structure
+ *
+ *  @return  psPolynomial4D*    new double-precision 4-D polynomial struct
+ */
+psDPolynomial4D* psDPolynomial4DAlloc(
+    int nW,                            ///< Number of terms in w
+    int nX,                            ///< Number of terms in x
+    int nY,                            ///< Number of terms in y
+    int nZ,                            ///< Number of terms in z
+    psPolynomialType type              ///< Polynomial Type
+);
+
+/** Evaluates a double-precision 1-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+double psDPolynomial1DEval(
+    double x,                          ///< Value at which to evaluate
+    const psDPolynomial1D* myPoly      ///< Coefficients for the polynomial
+);
+
+/** Evaluates a double-precision 2-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+double psDPolynomial2DEval(
+    double x,                           ///< Value x at which to evaluate
+    double y,                           ///< Value y at which to evaluate
+    const psDPolynomial2D* myPoly       ///< Coefficients for the polynomial
+);
+
+/** Evaluates a double-precision 3-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+double psDPolynomial3DEval(
+    double x,                          ///< Value x at which to evaluate
+    double y,                          ///< Value y at which to evaluate
+    double z,                          ///< Value z at which to evaluate
+    const psDPolynomial3D* myPoly      ///< Coefficients for the polynomial
+);
+
+/** Evaluates a double-precision 4-D polynomial at specific coordinates.
+ *
+ *  @return float    result of polynomial at given location
+ */
+double psDPolynomial4DEval(
+    double w,                          ///< Value w at which to evaluate
+    double x,                          ///< Value x at which to evaluate
+    double y,                          ///< Value y at which to evaluate
+    double z,                          ///< Value z at which to evaluate
+    const psDPolynomial4D* myPoly      ///< Coefficients for the polynomial
+);
+
+psVector *psDPolynomial1DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                    const psDPolynomial1D *myPoly  ///< Coefficients for the polynomial
+                                   );
+
+psVector *psDPolynomial2DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                    const psVector *y,             ///< y locations at which to evaluate
+                                    const psDPolynomial2D *myPoly  ///< Coefficients for the polynomial
+                                   );
+
+psVector *psDPolynomial3DEvalVector(const psVector *x,             ///< x locations at which to evaluate
+                                    const psVector *y,             ///< y locations at which to evaluate
+                                    const psVector *z,             ///< z locations at which to evaluate
+                                    const psDPolynomial3D *myPoly  ///< Coefficients for the polynomial
+                                   );
+
+psVector *psDPolynomial4DEvalVector(const psVector *w,             ///< w locations at which to evaluate
+                                    const psVector *x,             ///< x locations at which to evaluate
+                                    const psVector *y,             ///< y locations at which to evaluate
+                                    const psVector *z,             ///< z locations at which to evaluate
+                                    const psDPolynomial4D *myPoly  ///< Coefficients for the polynomial
+                                   );
+
+
+
+typedef struct
+{
+    int n;                        ///< The number of spline polynomials
+    psPolynomial1D **spline;      ///< An array of n pointers to the spline polynomials
+    float *p_psDeriv2;            ///< For cubic splines, the second derivative at each domain point.  Size is n+1.
+    float *domains;               ///< The boundaries between each spline piece.  Size is n+1.
+}
+psSpline1D;
+
+psSpline1D *psSpline1DAlloc(int n,
+                            int order,
+                            float min,
+                            float max);
+
+int p_psSpline1DFree(psSpline1D *tmpSpline);
+
+psSpline1D *psSpline1DAllocGeneric(const psVector *bounds,
+                                   int order);
+
+float psSpline1DEval(const psSpline1D *spline,
+                     float x);
+
+psVector *psSpline1DEvalVector(const psVector *x,
+                               const psSpline1D *spline);
+
+int p_psVectorBinDisectF32(float *bins,
+                           int numBins,
+                           float x);
+
+int p_psVectorBinDisectS32(int *bins,
+                           int numBins,
+                           int x);
+
+int p_psVectorBinDisect(psVector *bins,
+                        psScalar *x);
+
+psScalar *p_psVectorInterpolate(psVector *domain,
+                                psVector *range,
+                                int order,
+                                psScalar *x);
+
+float p_psNRSpline1DEval(psSpline1D *spline,
+                         const psVector* restrict x,
+                         const psVector* restrict y,
+                         float X);
+
+/* \} */// End of MathGroup Functions
+
+#endif
+
Index: /branches/rel3/psLib/src/math/psStats.c
===================================================================
--- /branches/rel3/psLib/src/math/psStats.c	(revision 2163)
+++ /branches/rel3/psLib/src/math/psStats.c	(revision 2163)
@@ -0,0 +1,1908 @@
+/** @file  psStats.c
+ *  \brief basic statistical operations
+ *  @ingroup Stats
+ *
+ *  This file will hold the definition of the histogram and stats data
+ *  structures.  It also contains prototypes for procedures which operate
+ *  on those data structures.
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.67 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-13 02:40:13 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <float.h>
+#include <math.h>
+
+/*****************************************************************************/
+/* INCLUDE FILES                                                             */
+/*****************************************************************************/
+#include "psMemory.h"
+#include "psImage.h"
+#include "psVector.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psStats.h"
+#include "psMinimize.h"
+#include "psFunctions.h"
+#include "psConstants.h"
+
+/*****************************************************************************/
+/* DEFINE STATEMENTS                                                         */
+/*****************************************************************************/
+// will use robust statistical methods.
+#define GAUSS_WIDTH 20                     // The width of the Gaussian or boxcar smoothing.
+#define CLIPPED_NUM_ITER_LB 1
+#define CLIPPED_NUM_ITER_UB 10
+#define CLIPPED_SIGMA_LB 1.0
+#define CLIPPED_SIGMA_UB 10.0
+#define true 1
+#define false 0
+#define MY_MAX_FLOAT HUGE
+#define MAX_ITERATIONS 10
+
+void p_psVectorRobustStats(const psVector* restrict myVector,
+                           const psVector* restrict maskVector, unsigned int maskVal, psStats* stats);
+
+
+/*****************************************************************************/
+/* TYPE DEFINITIONS                                                          */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* GLOBAL VARIABLES                                                          */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FILE STATIC VARIABLES                                                     */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - LOCAL                                           */
+/*****************************************************************************/
+
+bool p_psGetStatValue(const psStats* stats, double *value)
+{
+
+    switch (stats->options & ~(PS_STAT_USE_RANGE | PS_STAT_USE_BINSIZE | PS_STAT_ROBUST_FOR_SAMPLE)) {
+    case PS_STAT_SAMPLE_MEAN:
+        *value = stats->sampleMean;
+        return true;
+
+    case PS_STAT_SAMPLE_MEDIAN:
+        *value = stats->sampleMedian;
+        return true;
+
+    case PS_STAT_SAMPLE_STDEV:
+        *value = stats->sampleStdev;
+        return true;
+
+    case PS_STAT_ROBUST_MEAN:
+        *value = stats->robustMean;
+        return true;
+
+    case PS_STAT_ROBUST_MEDIAN:
+        *value = stats->robustMedian;
+        return true;
+
+    case PS_STAT_ROBUST_MODE:
+        *value = stats->robustMode;
+        return true;
+
+    case PS_STAT_ROBUST_STDEV:
+        *value = stats->robustStdev;
+        return true;
+
+    case PS_STAT_CLIPPED_MEAN:
+        *value = stats->clippedMean;
+        return true;
+
+    case PS_STAT_CLIPPED_STDEV:
+        *value = stats->clippedStdev;
+        return true;
+
+    case PS_STAT_MAX:
+        *value = stats->max;
+        return true;
+
+    case PS_STAT_MIN:
+        *value = stats->min;
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+/*****************************************************************************
+p_psVectorPrint(myVector, maskVector, maskVal, stats): a private internal
+function that simply prints a vector to STDOUT.  Used primarily for
+debugging.
+ *****************************************************************************/
+
+void p_psVectorPrint(psVector* myVector, psVector* maskVector, unsigned int maskVal, psStats* stats)
+{
+    int i = 0;                  // Loop index variable.
+
+    for (i = 0; i < myVector->n; i++) {
+        if (maskVector != NULL)
+            printf("Element %d is %f (mask is %d)\n", i, myVector->data.F32[i], maskVector->data.U8[i]);
+        else
+            printf("Element %d is %f\n", i, myVector->data.F32[i]);
+    }
+}
+
+/******************************************************************************
+ ******************************************************************************
+ ******************************************************************************
+    MISC PRIVATE STATISTICAL FUNCTIONS
+ 
+    NOTE: it is assumed that any call to these statistical functions will
+    have been preceded by a call to the psVectorStats() function.  Various
+    sanity tests will only be performed in psVectorStats().
+        Is the mask vector the same length as the data vector?
+        Is the mask vector of type PS_TYPE_U8?
+        Is the stats data structure NULL?
+        Is the in data structure NULL?
+        Is the in data structure of type PS_TYPE_F32?
+ ******************************************************************************
+ ******************************************************************************
+ *****************************************************************************/
+
+/******************************************************************************
+p_psVectorSampleMean(myVector, maskVector, maskVal, stats): calculates the
+mean of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ASSUMPTION: the mean is always calculated exactly.  Robust means are never
+calculated in this routine.
+ *****************************************************************************/
+
+void p_psVectorSampleMean(const psVector* restrict myVector,
+                          const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    int i = 0;                  // Loop index variable
+    float mean = 0.0;           // The mean
+    int count = 0;              // # of points in this mean?
+    float rangeMin = 0.0;       // Exclude data below this
+    float rangeMax = 0.0;       // Exclude date above this
+
+    // If PS_STAT_USE_RANGE is requested, then we enter a slightly different
+    // loop.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                // Check if the data is with the specified range
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    mean += myVector->data.F32[i];
+                    count++;
+                }
+            }
+            mean /= (float)count;
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    mean += myVector->data.F32[i];
+                    count++;
+                }
+            }
+            mean /= (float)count;
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    mean += myVector->data.F32[i];
+                    count++;
+                }
+            }
+            mean /= (float)count;
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                mean += myVector->data.F32[i];
+            }
+            mean /= (float)myVector->n;
+        }
+    }
+
+    stats->sampleMean = mean;
+}
+
+/******************************************************************************
+p_psVectorSampleMax(myVector, maskVector, maskVal, stats): calculates the
+max of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorMax(const psVector* restrict myVector,
+                   const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    int i = 0;                  // Loop index variable
+    float max = -MY_MAX_FLOAT;  // The calculated maximum
+    float rangeMin = 0.0;       // Exclude data below this
+    float rangeMax = 0.0;       // Exclude date above this
+
+    // If PS_STAT_USE_RANGE is requested, then we enter a different loop.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if ((myVector->data.F32[i] > max) &&
+                            (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                        max = myVector->data.F32[i];
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((myVector->data.F32[i] > max) &&
+                        (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    max = myVector->data.F32[i];
+                }
+            }
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if (myVector->data.F32[i] > max) {
+                        max = myVector->data.F32[i];
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if (myVector->data.F32[i] > max) {
+                    max = myVector->data.F32[i];
+                }
+            }
+        }
+    }
+
+    stats->max = max;
+}
+
+/******************************************************************************
+p_psVectorSampleMin(myVector, maskVector, maskVal, stats): calculates the
+minimum of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorMin(const psVector* restrict myVector,
+                   const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    int i = 0;                  // Loop index variable
+    float min = MY_MAX_FLOAT;   // The calculated maximum
+    float rangeMin = 0.0;       // Exclude data below this
+    float rangeMax = 0.0;       // Exclude date above this
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if ((myVector->data.F32[i] < min) &&
+                            (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                        min = myVector->data.F32[i];
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((myVector->data.F32[i] < min) &&
+                        (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    min = myVector->data.F32[i];
+                }
+            }
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    if (myVector->data.F32[i] < min) {
+                        min = myVector->data.F32[i];
+                    }
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if (myVector->data.F32[i] < min) {
+                    min = myVector->data.F32[i];
+                }
+            }
+        }
+    }
+
+    stats->min = min;
+}
+
+/******************************************************************************
+p_psVectorNValues(myVector, maskVector, maskVal, stats): calculates the
+number of non-masked pixels in the vector that fall within the min/max
+range, if given.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+int p_psVectorNValues(const psVector* restrict myVector,
+                      const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    int i = 0;                  // Loop index variable
+    int numData = 0;            // The number of data points
+    float rangeMin = 0.0;       // Exclude data below this
+    float rangeMax = 0.0;       // Exclude date above this
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    numData++;
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    numData++;
+                }
+            }
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    numData++;
+                }
+            }
+        } else {
+            numData = myVector->n;
+        }
+    }
+    return (numData);
+}
+
+/******************************************************************************
+p_psVectorSampleMedian(myVector, maskVector, maskVal, stats): calculates the
+median of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorSampleMedian(const psVector* restrict myVector,
+                            const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    psVector* unsortedVector = NULL;    // Temporary vector
+    psVector* sortedVector = NULL;      // Temporary vector
+    int i = 0;                  // Loop index variable
+    int count = 0;              // # of points in this mean?
+    int nValues = 0;            // # of points in vector
+    float rangeMin = 0.0;       // Exclude data below this
+    float rangeMax = 0.0;       // Exclude date above this
+
+    // Determine if the number of data points exceed a threshold which will
+    // cause to generate robust stats, as opposed to exact stats.
+    // XXX: This code is no longer used.  We now calculate the median exactly
+    // regardless of the vector size.
+    /*
+     * // Calculate the robust quartiles. stats2 = psStatsAlloc(PS_STAT_ROBUST_MEDIAN);
+     * p_psVectorRobustStats(myVector, maskVector, maskVal, stats2);
+     * 
+     * // Store the robust quartiles into the sample quartile members. stats->sampleMedian =
+     * stats2->robustMedian;
+     * 
+     * // Free temporary data buffers. psFree(stats2);
+     * 
+     * // Set the PS_STAT_ROBUST_FOR_SAMPLE bit in the stats structure. stats->options = stats->options |
+     * PS_STAT_ROBUST_FOR_SAMPLE;
+     * 
+     * return; } */
+
+    // Determine how many data points fit inside this min/max range
+    // and are not masked, IF the maskVector is not NULL>
+    nValues = p_psVectorNValues(myVector, maskVector, maskVal, stats);
+
+    // Allocate temporary vectors for the data.
+    unsortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
+    unsortedVector->n = unsortedVector->nalloc;
+
+    sortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
+    sortedVector->n = sortedVector->nalloc;
+
+    // Determine if we must only use data points within a min/max range.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+
+        // Store all non-masked data points within the min/max range
+        // into the temporary vectors.
+        count = 0;
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    unsortedVector->data.F32[count++] = maskVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        }
+    } else {
+        // Store all non-masked data points into the temporary vectors.
+        count = 0;
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                unsortedVector->data.F32[i] = myVector->data.F32[i];
+            }
+        }
+    }
+    // Sort the temporary vectors.
+    psVectorSort(sortedVector, unsortedVector);
+
+    // Calculate the median exactly.
+    // XXX: Is this the correct action?
+    if (0 == (nValues % 2)) {
+        stats->sampleMedian = 0.5 * (sortedVector->data.F32[(nValues / 2) - 1] +
+                                     sortedVector->data.F32[nValues / 2]);
+    } else {
+        stats->sampleMedian = sortedVector->data.F32[nValues / 2];
+    }
+
+    // Free the temporary data structures.
+    psFree(unsortedVector);
+    psFree(sortedVector);
+}
+
+/******************************************************************************
+    This routine smoothes the data in the input robustHistogram with a
+    Gaussian of width sigma.
+ 
+    XXX: Must consult with IfA on the proper values for the Gaussian
+    smoothing.  Currently, the Gaussian coefficients are such that only
+    the center coefficient is non-zero.  This is because "e" is being
+    raised to a very large negative number for all points except the
+    center point.
+ 
+    XXX: use a static variable for gaussianCoefs[] and compute them once.
+ *****************************************************************************/
+psVector* p_psVectorsmoothHistGaussian(psHistogram* robustHistogram,
+                                       float sigma)
+{
+    int i = 0;                  // Loop index variable
+    int j = 0;                  // Loop index variable
+    float denom = 0.0;          // Temporary variable
+    float expo = 0.0;           // Temporary variable
+    float gaussianCoefs[1 + (2 * GAUSS_WIDTH)]; // The Gaussian Coefficients
+    psVector* smooth = psVectorAlloc(robustHistogram->nums->n, PS_TYPE_F32);
+
+    for (i = 0; i < (1 + (2 * GAUSS_WIDTH)); i++) {
+        if (fabs(sigma) >= FLT_EPSILON) {
+            // If sigma does not equal zero, then we use Gaussian smoothing.
+            #ifdef  DARWIN
+            denom = (float)sqrt(2.0 * M_PI * sigma * sigma);
+            #else
+
+            denom = sqrtf(2.0 * M_PI * sigma * sigma);
+            #endif
+
+            expo = -(float)((i - GAUSS_WIDTH) * (i - GAUSS_WIDTH));
+            expo /= (2.0 * sigma * sigma);
+            gaussianCoefs[i] = exp(expo / denom);
+
+            //printf("p_psVectorsmoothHistGaussian(): gaussianCoefs[%d] is %f\n", i, gaussianCoefs[i]);
+            // NOTE: Gaussian smoothing just isn't working with low sigma
+            // values.  The problem is that the Gaussian coefficients are
+            // all zero, except for the middle coefficient, which is exactly
+            // one.  Therefore, I'm using boxcar smoothing.
+            gaussianCoefs[i] = 1.0 / (1.0 + (2.0 * (float)GAUSS_WIDTH));
+            // printf("gaussianCoefs[%d] is %f\n", i, gaussianCoefs[i]);
+        } else {
+            /* If sigma equals zero (all pixels have the same value) the above code will divide by zero.
+             * Therefore, we don't need to smooth the data. */
+            for (i = 0; i < robustHistogram->nums->n; i++) {
+                smooth->data.F32[i] = (float)robustHistogram->nums->data.S32[i];
+            }
+            return (smooth);
+        }
+    }
+
+    // Perform the actual smoothing.
+    for (i = 0; i < robustHistogram->nums->n; i++) {
+        smooth->data.F32[i] = 0.0;
+        for (j = -GAUSS_WIDTH; j <= +GAUSS_WIDTH; j++) {
+            if (((j + i) >= 0) && ((j + i) < smooth->n)) {
+                smooth->data.F32[i] += (gaussianCoefs[j + GAUSS_WIDTH] *
+                                        (float)robustHistogram->nums->data.S32[j + i]);
+            }
+        }
+    }
+    return (smooth);
+}
+
+/******************************************************************************
+p_psVectorSampleQuartiles(myVector, maskVector, maskVal, stats): calculates
+the upper and/or lower quartiles of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorSampleQuartiles(const psVector* restrict myVector,
+                               const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    psVector* unsortedVector = NULL;    // Temporary vector
+    psVector* sortedVector = NULL;      // Temporary vector
+    int i = 0;                  // Loop index variable
+    int count = 0;              // # of points in this mean?
+    int nValues = 0;            // # data points
+    float rangeMin = 0.0;       // Exclude data below this
+    float rangeMax = 0.0;       // Exclude date above this
+
+    // Determine how many data points fit inside this min/max range
+    // and are not maxed, IF the maskVector is not NULL>
+    nValues = p_psVectorNValues(myVector, maskVector, maskVal, stats);
+
+    // Allocate temporary vectors for the data.
+    unsortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
+    unsortedVector->n = unsortedVector->nalloc;
+    sortedVector = psVectorAlloc(nValues, PS_TYPE_F32);
+    sortedVector->n = sortedVector->nalloc;
+
+    // Determine if we must only use data points within a min/max range.
+    if (stats->options & PS_STAT_USE_RANGE) {
+        rangeMin = stats->min;
+        rangeMax = stats->max;
+        // Store all non-masked data points within the min/max range
+        // into the temporary vectors.
+        count = 0;
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        }
+    } else {
+        // Store all non-masked data points into the temporary vectors.
+        count = 0;
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    unsortedVector->data.F32[count++] = myVector->data.F32[i];
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                unsortedVector->data.F32[i] = myVector->data.F32[i];
+            }
+        }
+    }
+
+    // Sort the temporary vectors.
+    psVectorSort(sortedVector, unsortedVector);
+
+    // Calculate the quartile points exactly.
+    stats->sampleUQ = sortedVector->data.F32[3 * (nValues / 4)];
+    stats->sampleLQ = sortedVector->data.F32[nValues / 4];
+
+    // Free the temporary data structures.
+    psFree(unsortedVector);
+    psFree(sortedVector);
+}
+
+/******************************************************************************
+p_psVectorSampleStdev(myVector, maskVector, maskVal, stats): calculates the
+stdev of the input vector.
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ 
+ *****************************************************************************/
+void p_psVectorSampleStdev(const psVector* restrict myVector,
+                           const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    int i = 0;                  // Loop index variable
+    int countInt = 0;           // # of data points being used
+    float countFloat = 0.0;     // # of data points being used
+    float mean = 0.0;           // The mean
+    float diff = 0.0;           // Used in calculating stdev
+    float sumSquares = 0.0;     // temporary variable
+    float sumDiffs = 0.0;       // temporary variable
+    float rangeMin = 0.0;       // Exclude data below this
+    float rangeMax = 0.0;       // Exclude date above this
+
+    // This procedure requires the mean.  If it has not been already
+    // calculated, then call p_psVectorSampleMean()
+    if (0 != isnan(stats->sampleMean)) {
+        p_psVectorSampleMean(myVector, maskVector, maskVal, stats);
+    }
+    mean = stats->sampleMean;
+
+    if (stats->options & PS_STAT_USE_RANGE) {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i]) &&
+                        (rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares += (diff * diff);
+                    sumDiffs += diff;
+                    countInt++;
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                if ((rangeMin <= myVector->data.F32[i]) && (myVector->data.F32[i] <= rangeMax)) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares += (diff * diff);
+                    sumDiffs += diff;
+                    countInt++;
+                }
+            }
+            countInt = myVector->n;
+        }
+    } else {
+        if (maskVector != NULL) {
+            for (i = 0; i < myVector->n; i++) {
+                if (!(maskVal & maskVector->data.U8[i])) {
+                    diff = myVector->data.F32[i] - mean;
+                    sumSquares += (diff * diff);
+                    sumDiffs += diff;
+                    countInt++;
+                }
+            }
+        } else {
+            for (i = 0; i < myVector->n; i++) {
+                diff = myVector->data.F32[i] - mean;
+                sumSquares += (diff * diff);
+                sumDiffs += diff;
+                countInt++;
+            }
+            countInt = myVector->n;
+        }
+    }
+    countFloat = (float)countInt;
+
+    #ifdef DARWIN
+
+    stats->sampleStdev = (float)sqrt((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
+    #else
+
+    stats->sampleStdev = sqrtf((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
+    #endif
+}
+
+/******************************************************************************
+p_psVectorClippedStats(myVector, maskVector, maskVal, stats): calculates the
+clipped stats (mean or stdev) of the input vector.
+ 
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+ *****************************************************************************/
+void p_psVectorClippedStats(const psVector* restrict myVector,
+                            const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    int i = 0;                  // Loop index variable
+    int j = 0;                  // Loop index variable
+    float clippedMean = 0.0;    // self-explanatory
+    float clippedStdev = 0.0;   // self-explanatory
+    float oldStanMean = 0.0;    // Temporary variable
+    float oldStanStdev = 0.0;   // Temporary variable
+    psVector* tmpMask = NULL;   // Temporary vector
+
+    // Endure that stats->clipIter is within the proper range.
+    if (!((CLIPPED_NUM_ITER_LB <= stats->clipIter) && (stats->clipIter <= CLIPPED_NUM_ITER_UB))) {
+        psAbort(__func__, "Unallowed value for clipIter (%d).\n", stats->clipIter);
+    }
+    // Endure that stats->clipSigma is within the proper range.
+    if (!((CLIPPED_SIGMA_LB <= stats->clipSigma) && (stats->clipSigma <= CLIPPED_SIGMA_UB))) {
+        psAbort(__func__, "Unallowed value for clipSigma (%f).\n", stats->clipSigma);
+    }
+    // We allocate a temporary mask vector since during the iterative
+    // steps that follow, we will be masking off additional data points.
+    // However, we do no want to modify the original mask vector.
+    tmpMask = psVectorAlloc(myVector->n, PS_TYPE_U8);
+    tmpMask->n = myVector->n;
+
+    // If we were called with a mask vector, then initialize the temporary
+    // mask vector with those values.
+    if (maskVector != NULL) {
+        for (i = 0; i < tmpMask->n; i++) {
+            tmpMask->data.U8[i] = maskVector->data.U8[i];
+        }
+    }
+    // 1. Compute the sample median.
+    // NOTE: This seems odd.  Verify with IfA that we want to calculate the
+    // median here, not the mean.
+    p_psVectorSampleMedian(myVector, maskVector, maskVal, stats);
+
+    // 2. Compute the sample standard deviation.
+    p_psVectorSampleStdev(myVector, maskVector, maskVal, stats);
+
+    // 3. Use the sample median as the first estimator of the mean X.
+    clippedMean = stats->sampleMean;
+
+    // 4. Use the sample stdev as the first estimator of the mean stdev.
+    clippedStdev = stats->sampleStdev;
+
+    // Must save the old sampleMean and sampleStdev since the following code
+    // block overwrites them.
+    oldStanMean = stats->sampleMean;
+    oldStanStdev = stats->sampleStdev;
+
+    // 5. Repeat N times:
+    for (i = 0; i < stats->clipIter; i++) {
+        for (j = 0; j < myVector->n; j++) {
+            // a) Exclude all values x_i for which |x_i - x| > K * stdev
+            if (fabs(myVector->data.F32[j] - clippedMean) > (stats->clipSigma * clippedStdev)) {
+                tmpMask->data.U8[i] = 0xff;
+            }
+            // b) compute new mean and stdev
+            p_psVectorSampleMedian(myVector, tmpMask, maskVal, stats);
+            p_psVectorSampleStdev(myVector, tmpMask, maskVal, stats);
+
+            // c) Use the new mean for x
+            clippedMean = stats->sampleMean;
+
+            // d) Use the new stdev for stdev
+            clippedStdev = stats->sampleStdev;
+        }
+
+    }
+    stats->sampleMean = oldStanMean;
+    stats->sampleStdev = oldStanStdev;
+
+    // 7. The last calcuated value of x is the cliped mean.
+    if (stats->options & PS_STAT_CLIPPED_MEAN) {
+        stats->clippedMean = clippedMean;
+    }
+    // 8. The last calcuated value of stdev is the cliped stdev.
+    if (stats->options & PS_STAT_CLIPPED_STDEV) {
+        stats->clippedStdev = clippedStdev;
+    }
+
+    psFree(tmpMask);
+}
+
+/*****************************************************************************
+p_psNormalizeVectorF32(myData): this is a private function which normalizes the
+elements of a vector to a range between 0.0 and 1.0.
+ *****************************************************************************/
+void p_psNormalizeVectorF32(psVector* myData)
+{
+    float min = (float)HUGE;
+    float max = (float)-HUGE;
+    int i = 0;
+
+    for (i = 0; i < myData->n; i++) {
+        if (myData->data.F32[i] < min) {
+            min = myData->data.F32[i];
+        }
+        if (myData->data.F32[i] > max) {
+            max = myData->data.F32[i];
+        }
+    }
+
+    //  float range = max - min;
+    //    for (i = 0; i < myData->n; i++) {
+    //        myData->data.F32[i] = (myData->data.F32[i] - min) / range;
+    //    }
+    for (i = 0; i < myData->n; i++) {
+        myData->data.F32[i] = (myData->data.F32[i] - 0.5 * (min + max)) /
+                              (0.5 * (max - min));
+    }
+}
+
+/*****************************************************************************
+p_psNormalizeVectorF64(myData): this is a private function which normalizes the
+elements of a vector to a range between -1.0 and 1.0.
+XXX: 0-1 or -1:1?
+ *****************************************************************************/
+void p_psNormalizeVectorF64(psVector* myData)
+{
+    float min = (double)HUGE;
+    float max = (double)-HUGE;
+    double range = 0.0;
+    int i = 0;
+
+    for (i = 0; i < myData->n; i++) {
+        if (myData->data.F64[i] < min) {
+            min = myData->data.F64[i];
+        }
+        if (myData->data.F64[i] > max) {
+            max = myData->data.F64[i];
+        }
+    }
+
+    range = max - min;
+    for (i = 0; i < myData->n; i++) {
+        myData->data.F64[i] = -1.0 + 2.0 *
+                              ((myData->data.F64[i] - min) / range);
+    }
+
+    //    for (i = 0; i < myData->n; i++) {
+    //        myData->data.F64[i] = (myData->data.F64[i] - 0.5 * (min + max)) /
+    //                              (0.5 * (max - min));
+    //    }
+}
+
+void p_psNormalizeVector(psVector* myData)
+{
+    if (myData->type.type == PS_TYPE_F32) {
+        p_psNormalizeVectorF32(myData);
+    } else if (myData->type.type == PS_TYPE_F64) {
+        p_psNormalizeVectorF64(myData);
+    } else {
+        psError(__func__, "Unalowable data type.\n");
+    }
+}
+
+/*****************************************************************************
+p_psGaussian(myData, myParams): an internal function, used by robust stats,
+intended to compute the Gaussian with a specified sigma/mean, at the
+specified data point.
+ *****************************************************************************/
+float p_psGaussian(const psVector* restrict myData, const psVector* restrict myParams)
+{
+    float x = myData->data.F32[0];
+    float mean = myParams->data.F32[0];
+    float stdev = myParams->data.F32[1];
+    float tmp = exp(-((x - mean) * (x - mean)) / (2.0 * stdev * stdev));
+
+    tmp /= ((float)sqrt(2.0 * M_PI * (stdev * stdev)));
+
+    // printf("p_psGaussian((%.2f), %.2f, %.2f) is %.2f\n", x, mean, stdev, tmp);
+    return (tmp);
+}
+
+/*****************************************************************************
+p_psGaussianDeriv(myData, myParams, whichParam): an internal function, which
+calculates the specified partial derivative of the above Gaussian function.
+ *****************************************************************************/
+float p_psGaussianDeriv(const psVector* restrict myData, const psVector* restrict myParams, int whichParam)
+{
+    float x = myData->data.F32[0];
+    float mean = myParams->data.F32[0];
+    float stdev = myParams->data.F32[1];
+    float tmp = 0.0;
+
+    if (whichParam == 0) {
+        // Return the derivative w.r.t. the mean.
+        tmp = (x - mean) * p_psGaussian(myData, myParams);
+        tmp /= (stdev * stdev);
+    } else if (whichParam == 1) {
+        // Return the derivative w.r.t. the stdev.
+        tmp = (x - mean) * (x - mean) * p_psGaussian(myData, myParams);
+        tmp /= (stdev * stdev * stdev);
+    }
+    printf("p_psGaussianDeriv((%.2f), %.2f, %.2f, (%d)) is %.2f\n", x, mean, stdev, whichParam, tmp);
+
+    return (tmp);
+}
+
+/*****************************************************************************
+p_psQuadratic(myData, myParams): an internal function, used by robust stats,
+intended to compute a quadratic, with the specified parameters, at the
+specified data point.
+ *****************************************************************************/
+float p_psQuadratic(const psVector* restrict myParams, const psVector* restrict myCoords)
+{
+    float x = myCoords->data.F32[0];
+    float A = myParams->data.F32[0];
+    float B = myParams->data.F32[1];
+    float C = myParams->data.F32[2];
+    float tmp = 0.0;
+
+    tmp = (A * x * x) + (B * x) + C;
+    return (tmp);
+}
+
+/*****************************************************************************
+p_psQuadraticDeriv(myData, myParams, whichParam): an internal function, which
+calculates the specified partial derivative of the above quadratic function.
+ *****************************************************************************/
+float p_psQuadraticDeriv(const psVector* restrict myParams,
+                         const psVector* restrict myCoords, int whichParamDeriv)
+{
+    float x = myCoords->data.F32[0];
+    float tmp = 0.0;
+
+    if (whichParamDeriv == 0) {
+        tmp = x * x;
+    } else if (whichParamDeriv == 1) {
+        tmp = x;
+    } else if (whichParamDeriv == 2) {
+        tmp = 1.0;
+    }
+
+    return (tmp);
+}
+
+/******************************************************************************
+p_ps1DPolyMedian(myPoly, rangeLow, rangeHigh, midpoint): This routine takes
+as input a 1-D polynomial of arbitrary order (though we are using 2nd-order
+polynomials here) and a range of x-values for which it is defined:
+[rangeLow, rangeHigh].  It determines the x-value of that polynomial such
+that f(x) == midpoint.  This functions uses a binary-search algorithm on the
+range and assumes that the polynomial is monotonically increasing or
+decreasing within that range.
+ 
+XXX: Terminate when f(x)-getThisValue is within some error tolerance.
+ *****************************************************************************/
+float p_ps1DPolyMedian(psPolynomial1D* myPoly,
+                       float rangeLow,
+                       float rangeHigh,
+                       float getThisValue)
+{
+    int numIterations = 0;
+    float midpoint = 0.0;
+    float oldMidpoint = 1.0;
+    float f = 0.0;
+
+    // printf("p_ps1DPolyMedian(%f, %f, %f) \n", rangeLow, rangeHigh, getThisValue);
+
+    while (numIterations < MAX_ITERATIONS) {
+        midpoint = (rangeHigh + rangeLow) / 2.0;
+        if (fabs(midpoint - oldMidpoint) <= FLT_EPSILON) {
+            return (midpoint);
+        }
+        oldMidpoint = midpoint;
+
+        f = psPolynomial1DEval(midpoint, myPoly);
+        // printf("p_ps1DPolyMedian() iteration %d.  f(%f) is %f\n", numIterations, midpoint, f);
+        if (fabs(f - getThisValue) <= FLT_EPSILON) {
+            return (midpoint);
+        }
+
+        if (f > getThisValue) {
+            rangeHigh = midpoint;
+        } else {
+            rangeLow = midpoint;
+        }
+        numIterations++;
+    }
+    return (midpoint);
+}
+
+/******************************************************************************
+p_psFitQuadratic(robustHistogram. cumulativeSums, binNum, fitFloat): given
+the specified histogram, with the specified pre-calculated cumulativeSums,
+this routine fits a quadratic f(x) to the 3 bins surrounding bin "binNum",
+and then finds the point x such that f(x) == fitFloat.
+ 
+XXX: This function is currently not being used.
+ *****************************************************************************/
+float p_psFitQuadratic(psHistogram* histogram,
+                       psVector* cumulativeSums,
+                       int binNum,
+                       float fitFloat)
+{
+    psVector* x = psVectorAlloc(3, PS_TYPE_F64);
+    psVector* y = psVectorAlloc(3, PS_TYPE_F64);
+    psVector* yErr = psVectorAlloc(3, PS_TYPE_F64);
+    psPolynomial1D* myPoly = psPolynomial1DAlloc(2, PS_POLYNOMIAL_ORD);
+
+    if ((binNum > 0) && (binNum < (histogram->nums->n + 1))) {
+        x->data.F64[0] = (double)0.5 *
+                         (histogram->bounds->data.F32[binNum - 1] + histogram->bounds->data.F32[binNum]);
+        x->data.F64[1] = (double)0.5 *
+                         (histogram->bounds->data.F32[binNum] + histogram->bounds->data.F32[binNum + 1]);
+        x->data.F64[2] = (double)0.5 *
+                         (histogram->bounds->data.F32[binNum + 1] + histogram->bounds->data.F32[binNum + 2]);
+
+        y->data.F64[0] = cumulativeSums->data.F32[binNum - 1];
+        y->data.F64[1] = cumulativeSums->data.F32[binNum];
+        y->data.F64[2] = cumulativeSums->data.F32[binNum + 1];
+
+        if (!((y->data.F64[0] <= fitFloat) && (fitFloat <= y->data.F64[2]))) {
+            psAbort(__func__, "p_psVectorRobustStats(0): midpoint not within y-range\n");
+        }
+
+        yErr->data.F64[0] = 1.0;
+        yErr->data.F64[1] = 1.0;
+        yErr->data.F64[2] = 1.0;
+
+        myPoly = psVectorFitPolynomial1D(myPoly, x, y, yErr);
+        return (p_ps1DPolyMedian(myPoly, x->data.F64[0], x->data.F64[2], fitFloat));
+    } else {
+        return (0.5 * (histogram->bounds->data.F32[binNum + 1] + histogram->bounds->data.F32[binNum]));
+    }
+
+    psFree(x);
+    psFree(y);
+    psFree(yErr);
+    psFree(myPoly);
+    return (0.0);
+}
+
+/******************************************************************************
+p_psVectorRobustStats(myVector, maskVector, maskVal, stats): this procedure
+calculates a variety of robust stat measures:
+    PS_STAT_ROBUST_MEAN
+    PS_STAT_ROBUST_MEDIAN
+    PS_STAT_ROBUST_MODE
+    PS_STAT_ROBUST_STDEV
+    PS_STAT_ROBUST_QUARTILE
+I have included all that computation in a single function, as opposed to
+breaking it across several functions for one primary reason:  they all
+require the same basic initial processing steps (calculate the histogram,
+etc.)  however there is no currently defined means, in the SDRS, to specify
+this computation as a separate step.  If the above robust stat measures were
+calcualted in separate functiosn, then much of the initial processing would
+be duplicated.
+ 
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    NULL
+*****************************************************************************/
+void p_psVectorRobustStats(const psVector* restrict myVector,
+                           const psVector* restrict maskVector, unsigned int maskVal, psStats* stats)
+{
+    psHistogram* robustHistogram = NULL;
+    psVector* robustHistogramVector = NULL;
+    float binSize = 0.0;        // Size of the histogram bins
+    int LQBinNum = -1;          // Bin num for lower quartile
+    int UQBinNum = -1;          // Bin num for upper quartile
+    int i = 0;                  // Loop index variable
+    int maxBinNum = 0;
+    float maxBinCount = 0.0;
+    float dL = 0.0;
+    int numBins = 0;
+    psStats* tmpStats = psStatsAlloc(PS_STAT_CLIPPED_STDEV | PS_STAT_CLIPPED_MEAN);
+
+    // psImage* domain;
+    // psVector* errors;
+    // psVector* data;
+    // psVector* initialGuess;
+    // psVector* theParams;
+    // float chiSq=0.0;
+    // float max = -HUGE;
+    // float max_pos;
+    float myMean = 0.0;
+    float myStdev = 0.0;
+    float countFloat = 0.0;
+    float diff = 0.0;
+    float sumSquares = 0.0;
+    float sumDiffs = 0.0;
+    psVector* x = psVectorAlloc(3, PS_TYPE_F64);
+    psVector* y = psVectorAlloc(3, PS_TYPE_F64);
+    psVector* yErr = psVectorAlloc(3, PS_TYPE_F64);
+    psPolynomial1D* myPoly = psPolynomial1DAlloc(2, PS_POLYNOMIAL_ORD);
+    psVector* cumulativeRobustSumsFullRange = NULL;
+    psVector* cumulativeRobustSumsDlRange = NULL;
+    float sumRobust = 0.0;
+    float sumN50 = 0.0;
+    float sumNfit = 0.0;
+    float cumulativeMedian = 0.0;
+
+    // Compute the initial bin size of the robust histogram.  This is done
+    // by computing the clipped standard deviation of the vector, and dividing
+    // that by 10.0;
+    p_psVectorClippedStats(myVector, maskVector, maskVal, tmpStats);
+    binSize = tmpStats->clippedStdev / 10.0f;
+
+    // If stats->clippedStdev == 0.0, then all data elements have the same
+    // value.  Therefore, we can set the appropiate results and return.
+    if (fabs(binSize) <= FLT_EPSILON) {
+        if (stats->options & PS_STAT_ROBUST_MEAN) {
+            stats->robustMean = stats->clippedMean;
+        }
+        if (stats->options & PS_STAT_ROBUST_MEDIAN) {
+            stats->robustMedian = stats->clippedMean;
+        }
+        if (stats->options & PS_STAT_ROBUST_MODE) {
+            stats->robustMode = stats->clippedMean;
+        }
+        if (stats->options & PS_STAT_ROBUST_STDEV) {
+            stats->robustStdev = 0.0;
+        }
+        if (stats->options & PS_STAT_ROBUST_QUARTILE) {
+            stats->robustUQ = stats->clippedMean;
+            stats->robustLQ = stats->clippedMean;
+        }
+        // XXX: Set these to the number of unmasked data points?
+        stats->robustNfit = 0.0;
+        stats->robustN50 = 0.0;
+        psFree(tmpStats);
+        return;
+    }
+    // Determine minimum and maximum values in the data vector.
+    if (isnan(stats->min)) {
+        p_psVectorMin(myVector, maskVector, maskVal, stats);
+    }
+    if (isnan(stats->max)) {
+        p_psVectorMax(myVector, maskVector, maskVal, stats);
+    }
+    // Create the histogram structure.  NOTE: we can not specify the bin size
+    // precisely since the argument to psHistogramAlloc() is the number of
+    // bins, not the binSize.  Also, if we get here, we know that
+    // binSize != 0.0.
+    numBins = (int)((stats->max - stats->min) / binSize);
+    robustHistogram = psHistogramAlloc(stats->min, stats->max, numBins);
+
+    // Populate the histogram array.
+    psVectorHistogram(robustHistogram, myVector, maskVector, maskVal);
+
+    // Smooth the histogram.
+    // XXX: is that the right stdev?
+    robustHistogramVector = p_psVectorsmoothHistGaussian(robustHistogram,
+                            tmpStats->clippedStdev / 4.0f);
+
+    // The following was necessary to fit a gaussian to the data, since
+    // gaussian functions produce data between 0.0 and 1.0.
+    // p_psNormalizeVectorF32(robustHistogramVector);
+
+    /**************************************************************************
+    Determine the lower/upper quartiles.
+    **************************************************************************/
+    // We define a vector called "cumulativeRobustSums..." where the value at
+    // index position i is equal to the sum of bins 0:i.  This will be used
+    // now and later in determining the lower/upper quartiles.
+    cumulativeRobustSumsFullRange = psVectorAlloc(robustHistogramVector->n, PS_TYPE_F32);
+    cumulativeRobustSumsFullRange->data.F32[0] = robustHistogramVector->data.F32[0];
+    for (i = 1; i < robustHistogramVector->n; i++) {
+        cumulativeRobustSumsFullRange->data.F32[i] =
+            cumulativeRobustSumsFullRange->data.F32[i - 1] + robustHistogramVector->data.F32[i];
+    }
+    sumRobust = cumulativeRobustSumsFullRange->data.F32[robustHistogramVector->n - 1];
+
+    // Determine the bin number containing the lower quartile point.
+    LQBinNum = -1;
+    for (i = 0; i < cumulativeRobustSumsFullRange->n; i++) {
+        if (cumulativeRobustSumsFullRange->data.F32[i] >= (sumRobust / 4.0)) {
+            LQBinNum = i;
+            break;
+        }
+    }
+
+    // Determine the bin number containing the upper quartile point.
+    UQBinNum = -1;
+    for (i = cumulativeRobustSumsFullRange->n - 1; i >= 0; i--) {
+        if (cumulativeRobustSumsFullRange->data.F32[i] <= (3.0 * sumRobust / 4.0)) {
+            UQBinNum = i;
+            break;
+        }
+    }
+
+    if ((LQBinNum == -1) || (UQBinNum == -1)) {
+        psAbort(__func__, "Could not determine the robust lower/upper quartiles.");
+    }
+
+    /**************************************************************************
+    Determine the mode in the range LQ:UQ.
+    **************************************************************************/
+    // Determine the bin with the peak value in the range LQ to UQ.
+    maxBinNum = LQBinNum;
+    maxBinCount = robustHistogramVector->data.F32[LQBinNum];
+    sumN50 = (float)robustHistogram->nums->data.S32[LQBinNum];
+    for (i = LQBinNum + 1; i <= UQBinNum; i++) {
+        if (robustHistogramVector->data.F32[i] > maxBinCount) {
+            maxBinNum = i;
+            maxBinCount = robustHistogramVector->data.F32[i];
+        }
+        sumN50 += (float)robustHistogram->nums->data.S32[i];
+    }
+
+    // XXX: is dL defined as the value at the LQ/UQ, or the bin number?
+    dL = (UQBinNum - LQBinNum) / 4;
+
+    printf("(LQBinNum, UQBinNum, maxBinNum) is (%d, %d, %d)\n", LQBinNum, UQBinNum, maxBinNum);
+
+    /**************************************************************************
+    Determine the mean/stdev for the bins in the range mode-dL to mode+dL
+    **************************************************************************/
+    cumulativeRobustSumsDlRange = psVectorAlloc(robustHistogramVector->n, PS_TYPE_F32);
+    for (i = 0; i < robustHistogramVector->n; i++) {
+        cumulativeRobustSumsDlRange->data.F32[i] = 0.0;
+    }
+    sumNfit = 0.0;
+    cumulativeMedian = 0.0;
+    for (i = maxBinNum - dL; i <= maxBinNum + dL; i++) {
+        if ((0 <= i) && (i < robustHistogramVector->n)) {
+            cumulativeRobustSumsDlRange->data.F32[i] =
+                cumulativeRobustSumsDlRange->data.F32[i - 1] + robustHistogramVector->data.F32[i];
+            cumulativeMedian += robustHistogramVector->data.F32[i];
+            sumNfit += (float)robustHistogram->nums->data.S32[i];
+        }
+    }
+
+    // Calculate the mean of the smoothed robust histogram in the range
+    // mode-dL to mode+dL.  We use the midpoint of each bin as the mean for
+    // that bin (this is a non-exact approximation).
+    myMean = 0.0;
+    for (i = maxBinNum - dL; i <= maxBinNum + dL; i++) {
+        if ((0 <= i) && (i < robustHistogramVector->n)) {
+            myMean += (robustHistogramVector->data.F32[i]) * 0.5 *
+                      (robustHistogram->bounds->data.F32[i + 1] + robustHistogram->bounds->data.F32[i]);
+            countFloat += robustHistogramVector->data.F32[i];
+        }
+    }
+    myMean /= countFloat;
+
+    // Calculate the stdev of the smoothed robust histogram in the range
+    // mode-dL to mode+dL.  We use the midpoint of each bin as the mean for
+    // that bin.
+    for (i = maxBinNum - dL; i <= maxBinNum + dL; i++) {
+        if ((0 <= i) && (i < robustHistogramVector->n)) {
+            diff = (0.5 * (robustHistogram->bounds->data.F32[i + 1] +
+                           robustHistogram->bounds->data.F32[i])) - myMean;
+            sumSquares += diff * diff * robustHistogramVector->data.F32[i];
+            sumDiffs += diff * robustHistogramVector->data.F32[i];
+        }
+    }
+    myStdev = sqrt((sumSquares - (sumDiffs * sumDiffs / countFloat)) / (countFloat - 1));
+
+    /**************************************************************************
+    Set the appropriate members in the output stats struct.
+    **************************************************************************/
+    if (stats->options & PS_STAT_ROBUST_MEAN) {
+        stats->robustMean = myMean;
+    }
+
+    if (stats->options & PS_STAT_ROBUST_MODE) {
+        stats->robustMode = 0.5 *
+                            (robustHistogram->bounds->data.F32[maxBinNum] + robustHistogram->bounds->data.F32[maxBinNum + 1]);
+    }
+
+    if (stats->options & PS_STAT_ROBUST_STDEV) {
+        stats->robustStdev = myStdev;
+    }
+    // To determine the median (and later, the lower/upper quartile), we fit
+    // a quadratic to the three bins surrounding the bin containing the median.
+    // The quadratic y=f(x) with x being the midpoint of each bin, and y being
+    // the cumulative number of data points in all bins up to, and including,
+    // this bin.  We then solve the quadratic for
+
+    // XXX: Create a "p_psQuadraticFitAndSolveForX() function.
+
+    if (stats->options & PS_STAT_ROBUST_MEDIAN) {
+        if ((maxBinNum > 0) && (maxBinNum < (robustHistogram->nums->n - 1))) {
+            x->data.F64[0] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[maxBinNum - 1] +
+                              robustHistogram->bounds->data.F32[maxBinNum]);
+            x->data.F64[1] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[maxBinNum] +
+                              robustHistogram->bounds->data.F32[maxBinNum + 1]);
+            x->data.F64[2] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[maxBinNum + 1] +
+                              robustHistogram->bounds->data.F32[maxBinNum + 2]);
+
+            y->data.F64[0] = cumulativeRobustSumsDlRange->data.F32[maxBinNum - 1];
+            y->data.F64[1] = cumulativeRobustSumsDlRange->data.F32[maxBinNum];
+            y->data.F64[2] = cumulativeRobustSumsDlRange->data.F32[maxBinNum + 1];
+
+            // Ensure that cumulativeMedian/2 is actually within the range of the bins
+            // we are using.
+            cumulativeMedian *= 0.5;
+            if (!((y->data.F64[0] <= cumulativeMedian) && (cumulativeMedian <= y->data.F64[2]))) {
+                printf("((%f), %f, %f)\n", cumulativeMedian, y->data.F64[0], y->data.F64[2]);
+                psAbort(__func__, "p_psVectorRobustStats(1): midpoint not within y-range\n");
+            }
+            // XXX: yErr is not currently used by psVectorFitPolynomial1D().  We
+            // may have to set this meaningfully later.
+            yErr->data.F64[0] = 1.0;
+            yErr->data.F64[1] = 1.0;
+            yErr->data.F64[2] = 1.0;
+
+            // Determine the coefficients of the polynomial.
+            myPoly = psVectorFitPolynomial1D(myPoly, x, y, yErr);
+            // Call p_ps1DPolyMedian(), which does a binary search on the
+            // polynomial, looking for the value x such that
+            // f(x) = cumulativeMedian.
+            stats->robustMedian = p_ps1DPolyMedian(myPoly, x->data.F64[0], x->data.F64[2], cumulativeMedian);
+        } else {
+            // If the mode is the first/last histogram bin, then simply use
+            // the midpoint of that bin.
+            stats->robustMedian = 0.5 * (robustHistogram->bounds->data.F32[maxBinNum + 1] +
+                                         robustHistogram->bounds->data.F32[maxBinNum]);
+        }
+    }
+    // The lower/upper quartile calculations are very similar to the median
+    // calculations.  We fit a quadratic to the array containing the
+    // cumulative data points in each bin, then search for x such that
+    // f(x) equals the lower/upper quartile exactly.
+    //
+    if (stats->options & PS_STAT_ROBUST_QUARTILE) {
+        countFloat = cumulativeRobustSumsFullRange->data.F32[robustHistogramVector->n - 1];
+
+        if ((LQBinNum > 0) && (LQBinNum < (robustHistogram->nums->n - 1))) {
+            x->data.F64[0] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[LQBinNum - 1] +
+                              robustHistogram->bounds->data.F32[LQBinNum]);
+            x->data.F64[1] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[LQBinNum] +
+                              robustHistogram->bounds->data.F32[LQBinNum + 1]);
+            x->data.F64[2] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[LQBinNum + 1] +
+                              robustHistogram->bounds->data.F32[LQBinNum + 2]);
+
+            y->data.F64[0] = cumulativeRobustSumsFullRange->data.F32[LQBinNum - 1];
+            y->data.F64[1] = cumulativeRobustSumsFullRange->data.F32[LQBinNum];
+            y->data.F64[2] = cumulativeRobustSumsFullRange->data.F32[LQBinNum + 1];
+
+            if (!((y->data.F64[0] <= (countFloat / 4.0)) && ((countFloat / 4.0) <= y->data.F64[2]))) {
+                psAbort(__func__, "p_psVectorRobustStats(2): midpoint not within y-range\n");
+            }
+
+            yErr->data.F64[0] = 1.0;
+            yErr->data.F64[1] = 1.0;
+            yErr->data.F64[2] = 1.0;
+
+            myPoly = psVectorFitPolynomial1D(myPoly, x, y, yErr);
+            stats->robustLQ = p_ps1DPolyMedian(myPoly, x->data.F64[0], x->data.F64[2], countFloat / 4.0);
+
+        } else {
+            // If the LQ is the first/last histogram bin, then simply use
+            // the midpoint of that bin.
+            stats->robustLQ = 0.5 * (robustHistogram->bounds->data.F32[LQBinNum + 1] +
+                                     robustHistogram->bounds->data.F32[LQBinNum]);
+        }
+
+        if ((UQBinNum > 0) && (UQBinNum < (robustHistogram->nums->n - 1))) {
+            x->data.F64[0] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[UQBinNum - 1] +
+                              robustHistogram->bounds->data.F32[UQBinNum]);
+            x->data.F64[1] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[UQBinNum] +
+                              robustHistogram->bounds->data.F32[UQBinNum + 1]);
+            x->data.F64[2] = (double)0.5 *
+                             (robustHistogram->bounds->data.F32[UQBinNum + 1] +
+                              robustHistogram->bounds->data.F32[UQBinNum + 2]);
+
+            y->data.F64[0] = cumulativeRobustSumsFullRange->data.F32[UQBinNum - 1];
+            y->data.F64[1] = cumulativeRobustSumsFullRange->data.F32[UQBinNum];
+            y->data.F64[2] = cumulativeRobustSumsFullRange->data.F32[UQBinNum + 1];
+
+            if (!((y->data.F64[0] <= (3.0 * countFloat / 4.0)) &&
+                    ((3.0 * countFloat / 4.0) <= y->data.F64[2]))) {
+                psAbort(__func__, "p_psVectorRobustStats(3): midpoint not within y-range\n");
+            }
+
+            yErr->data.F64[0] = 1.0;
+            yErr->data.F64[1] = 1.0;
+            yErr->data.F64[2] = 1.0;
+
+            myPoly = psVectorFitPolynomial1D(myPoly, x, y, yErr);
+            stats->robustUQ = p_ps1DPolyMedian(myPoly,
+                                               x->data.F64[0], x->data.F64[2], 3.0 * countFloat / 4.0);
+        } else {
+            // If the UQ is the first/last histogram bin, then simply use
+            // the midpoint of that bin.
+            stats->robustUQ = 0.5 * (robustHistogram->bounds->data.F32[UQBinNum + 1] +
+                                     robustHistogram->bounds->data.F32[UQBinNum]);
+        }
+    }
+    stats->robustNfit = sumNfit;
+    stats->robustN50 = sumN50;
+
+    psFree(x);
+    psFree(y);
+    psFree(yErr);
+    psFree(tmpStats);
+    psFree(robustHistogram);
+    psFree(myPoly);
+    psFree(cumulativeRobustSumsFullRange);
+    psFree(cumulativeRobustSumsDlRange);
+}
+
+/*
+void p_ps_FitTheGaussian()
+{
+    // Fit a Gaussian to the bins in the range MODE-dL to Mode+dL
+    // NOTE: This code uses the psMinimize.c functions to perform
+    // the fit.  It doesn't quite work, 100% of the time.  For the time being
+    // I am commenting this code out, and replacing it with code which
+    // calculates the mean directly on the robustHistogram.
+    //
+    // XXX: Replace this with the LaGrange interpolation stuff.
+ 
+    domain = psImageAlloc(1, robustHistogramVector->n, PS_TYPE_F32);
+    errors = psVectorAlloc(robustHistogramVector->n, PS_TYPE_F32);
+    data = psVectorAlloc(robustHistogramVector->n, PS_TYPE_F32);
+    initialGuess = psVectorAlloc(2, PS_TYPE_F32);
+ 
+    max = -HUGE;
+    max_pos = -1;
+    for (i=0;i<robustHistogramVector->n;i++) {
+        domain->data.F32[i][0] = 0.5 * (robustHistogram->bounds->data.F32[i+1] +
+                                        robustHistogram->bounds->data.F32[i]);
+        data->data.F32[i] = (float) robustHistogramVector->data.F32[i];
+        errors->data.F32[i] = 1.0;
+        //printf("DATA (%.2f, %.2f)\n", domain->data.F32[i][0], data->data.F32[i]);
+        if (data->data.F32[i] > max) {
+            max = data->data.F32[i];
+            max_pos = domain->data.F32[i][0];
+        }
+    }
+ 
+    initialGuess->data.F32[0] = max_pos;
+    initialGuess->data.F32[1] = 1.0;
+    printf("Initial (mean. stdev) is (%.3f, %.3f)\n", initialGuess->data.F32[0], initialGuess->data.F32[1]);
+ 
+    printf("Calling psMinimizeChi2()\n");
+    theParams = psMinimizeChi2(p_psGaussian,
+                               p_psGaussianDeriv,
+                               domain,
+                               data,
+                               errors,
+                               initialGuess,
+                               NULL,
+                               &chiSq);
+    printf("Called psMinimizeChi2()\n");
+    printf("p_psVectorRobustStats() is (%f, %f)\n", theParams->data.F32[0], theParams->data.F32[1]);
+}
+*/
+
+/*****************************************************************************/
+
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+
+/*****************************************************************************/
+
+static void histogramFree(psHistogram* myHist);
+
+/******************************************************************************
+    psStatsAlloc(): This routine must create a new psStats data structure.
+ *****************************************************************************/
+psStats* psStatsAlloc(psStatsOptions options)
+{
+    psStats* newStruct = NULL;
+
+    newStruct = (psStats* ) psAlloc(sizeof(psStats));
+    newStruct->sampleMean = NAN;
+    newStruct->sampleMedian = NAN;
+    newStruct->sampleStdev = NAN;
+    newStruct->sampleUQ = NAN;
+    newStruct->sampleLQ = NAN;
+    newStruct->robustMean = NAN;
+    newStruct->robustMedian = NAN;
+    newStruct->robustMode = NAN;
+    newStruct->robustStdev = NAN;
+    newStruct->robustUQ = NAN;
+    newStruct->robustLQ = NAN;
+    newStruct->robustN50 = 0;
+    newStruct->robustNfit = 0;
+    newStruct->clippedMean = NAN;
+    newStruct->clippedStdev = NAN;
+    newStruct->clipSigma = 3.0;
+    newStruct->clipIter = 3.0;
+    newStruct->min = NAN;
+    newStruct->max = NAN;
+    newStruct->binsize = NAN;
+    newStruct->options = options;
+
+    return (newStruct);
+}
+
+/******************************************************************************
+psHistogramAlloc(lower, upper, n): allocate a uniform histogram structure
+with the specifed upper and lower limits, and the specifed number of bins.
+This routine will also set the bounds for each of the bins.
+ 
+Input:
+    lower
+    upper
+    n
+Returns:
+    The histogram structure
+ *****************************************************************************/
+psHistogram* psHistogramAlloc(float lower, float upper, int n)
+{
+    int i = 0;                  // Loop index variable
+    psHistogram* newHist = NULL;        // The new histogram structure
+    float binSize = 0.0;        // The histogram bin size
+
+    // NOTE: Verify that this is the correct action.
+    if (n == 0) {
+        return (NULL);
+    }
+    if (n < 0) {
+        psAbort(__func__, "psHistogramAlloc() called with bin size %d.\n", n);
+    }
+    // NOTE: Verify that this is the correct action.
+    if (lower > upper) {
+        return (NULL);
+    }
+    // Allocate memory for the new histogram structure.  If there are N
+    // bins, then there are N+1 bounds to those bins.
+    newHist = (psHistogram* ) psAlloc(sizeof(psHistogram));
+    p_psMemSetDeallocator(newHist, (psFreeFcn) histogramFree);
+    newHist->bounds = psVectorAlloc(n + 1, PS_TYPE_F32);
+    newHist->bounds->n = newHist->bounds->nalloc;
+
+    // Calculate the bounds for each bin.
+    binSize = (upper - lower) / (float)n;
+    // NOTE: Is the following necessary? It prevents the max data point
+    // from being in a non-existant bin.
+    binSize += FLT_EPSILON;
+    for (i = 0; i < n + 1; i++) {
+        newHist->bounds->data.F32[i] = lower + (binSize * (float)i);
+    }
+
+    // Allocate the bins, and initialize them to zero.
+    newHist->nums = psVectorAlloc(n, PS_TYPE_U32);
+    newHist->nums->n = newHist->nums->nalloc;
+    for (i = 0; i < newHist->nums->n; i++) {
+        newHist->nums->data.U32[i] = 0;
+    }
+
+    // Initialize the other members.
+    newHist->minNum = 0;
+    newHist->maxNum = 0;
+    newHist->uniform = true;
+
+    return (newHist);
+}
+
+/******************************************************************************
+psHistogramAllocGenric(bounds): allocate a non-uniform histogram structure
+with the specifed bounds.
+ 
+Input:
+    bounds
+Returns:
+    The histogram structure
+ *****************************************************************************/
+psHistogram* psHistogramAllocGeneric(const psVector* restrict bounds)
+{
+    psHistogram* newHist = NULL;        // The new histogram structure
+    int i;                      // Loop index variable
+
+    // NOTE: Verify that this is the correct action.
+    if (bounds == NULL) {
+        // psAbort(__func__, "psHistogram requested with NULL bounds");
+        return (NULL);
+    }
+    // NOTE: Verify that this is the correct action.
+    if (bounds->n <= 1) {
+        // psAbort(__func__, "psHistogram requested with NULL bounds");
+        return (NULL);
+    }
+
+    if (bounds->type.type != PS_TYPE_F32) {
+        // psAbort(__func__, "psHistogram request a bound which is not type F32");
+        return (NULL);
+    }
+    // Allocate memory for the new histogram structure.
+    newHist = (psHistogram* ) psAlloc(sizeof(psHistogram));
+    p_psMemSetDeallocator(newHist, (psFreeFcn) histogramFree);
+    newHist->bounds = psVectorAlloc(bounds->n, PS_TYPE_F32);
+    newHist->bounds->n = newHist->bounds->nalloc;
+    for (i = 0; i < bounds->n; i++) {
+        newHist->bounds->data.F32[i] = bounds->data.F32[i];
+    }
+
+    // Allocate the bins, and initialize them to zero.  If there are N bounds,
+    // then there are N-1 bins.
+    newHist->nums = psVectorAlloc((bounds->n) - 1, PS_TYPE_U32);
+    newHist->nums->n = newHist->nums->nalloc;
+    for (i = 0; i < newHist->nums->n; i++) {
+        newHist->nums->data.U32[i] = 0;
+    }
+
+    // Initialize the other members.
+    newHist->minNum = 0;
+    newHist->maxNum = 0;
+    newHist->uniform = false;
+
+    return (newHist);
+}
+
+static void histogramFree(psHistogram* myHist)
+{
+    psFree(myHist->bounds);
+    psFree(myHist->nums);
+}
+
+/*****************************************************************************
+psVectorHistogram(out, in, mask, maskVal): this procedure takes as input a
+preallocated and initialized histogram structure.  It fills the bins in that
+histogram structure in accordance with the input data "in" and the, possibly
+NULL, mask vector.
+ 
+Inputs:
+    out
+    in
+    mask
+    maskVal
+Returns:
+    The histogram structure "out".
+ *****************************************************************************/
+psHistogram* psVectorHistogram(psHistogram* out,
+                               const psVector* restrict in,
+                               const psVector* restrict mask,
+                               unsigned int maskVal)
+{
+    int i = 0;                  // Loop index variable
+    float binSize = 0.0;        // Histogram bin size
+    int binNum = 0;             // A temporary bin number
+    int numBins = 0;            // The total number of bins
+    int tmp = 0;
+    psScalar tmpScalar;
+    tmpScalar.type.type = PS_TYPE_F32;
+
+    // NOTE: Verify that this is the correct action.
+    if (out == NULL) {
+        return (NULL);
+    }
+    // Check the specified output histogram for type psF32
+    if (out->bounds->type.type != PS_TYPE_F32) {
+        psAbort(__func__, "Only data type PS_TYPE_F32 for the output.bounds member.");
+    }
+
+    if (out->nums->type.type != PS_TYPE_U32) {
+        psAbort(__func__, "Only data type PS_TYPE_U32 for output.nums member.");
+    }
+    // NOTE: Verify that this is the correct action.
+    if (in == NULL) {
+        return (out);
+    }
+
+    if (in->type.type != PS_TYPE_F32) {
+        psAbort(__func__, "Only data type PS_TYPE_F32 is currently supported (0x%x).", in->type.type);
+    }
+
+    if (mask != NULL) {
+        if (in->n != mask->n) {
+            psAbort(__func__, "Vector data and vector mask are of different sizes.");
+        }
+        if (mask->type.type != PS_TYPE_U8) {
+            psAbort(__func__, "Vector mask must be type PS_TYPE_U8");
+        }
+    }
+
+    // NOTE: determine the correct action for a variety of other cases:
+    // in vector has 0 elements, and histogram structure has zero bins.
+
+    numBins = out->nums->n;
+    for (i = 0; i < in->n; i++) {
+        // Check if this pixel is masked, and if so, skip it.
+        if ((mask == NULL) || ((mask != NULL) && (!(mask->data.U8[i] & maskVal)))) {
+            // Check if this pixel is below the minimum value, and if so
+            // count it, then skip it.
+            if (in->data.F32[i] < out->bounds->data.F32[0]) {
+                out->minNum++;
+                // Check if this pixel is above the maximum value, and if so
+                // count it, then skip it.
+            } else if (in->data.F32[i] > out->bounds->data.F32[numBins]) {
+                out->maxNum++;
+            } else {
+                // If this is a uniform histogram, determining the correct
+                // number is trivial.
+                if (out->uniform == true) {
+                    binSize = out->bounds->data.F32[1] - out->bounds->data.F32[0];
+                    binNum = (int)((in->data.F32[i] - out->bounds->data.F32[0]) / binSize);
+
+                    // NOTE: This next if-statement really shouldn't be necessary.
+                    // However, do to numerical lack of precision, we occasionally
+                    // produce a binNum outside the range of bins.
+                    if (binNum >= out->nums->n) {
+                        binNum = out->nums->n - 1;
+                    }
+
+                    (out->nums->data.S32[binNum])++;
+
+                    // If this is a non-uniform histogram, determining the correct
+                    // bin number requires a bit more work.
+                } else {
+                    tmpScalar.data.F32 = in->data.F32[i];
+                    tmp = p_psVectorBinDisect(out->bounds,
+                                              &tmpScalar);
+                    if (tmp == -1) {
+                        //                      XXX: Generate warning message
+                    } else {
+                        (out->nums->data.S32[tmp])++;
+                    }
+                }
+            }
+        }
+    }
+    return (out);
+}
+
+/******************************************************************************
+p_psConvertToF32(myVector, maskVector, maskVal, stats): this is the cheap
+way to support a variety of vector data types: we simply convert the input
+vector to F32 at the beginning, and write all of our functions in F32.  If
+the vast majority of all vector stat operations are F32 (or any other single
+type), then this is probably the best way to go.  Otherwise, when the
+algorithms stablize, we will then macro everything and put type support in
+the various stat functions.
+ 
+XXX: Should the default data type be F64?  Since we are buying Athlons...
+ *****************************************************************************/
+psVector* p_psConvertToF32(psStats* stats, psVector* in, psVector* mask, unsigned int maskVal)
+{
+    int i = 0;
+    psVector* tmp = NULL;
+
+    if (in->type.type == PS_TYPE_S8) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (float)in->data.S8[i];
+        }
+    } else if (in->type.type == PS_TYPE_U16) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (float)in->data.U16[i];
+        }
+    } else if (in->type.type == PS_TYPE_F64) {
+        tmp = psVectorAlloc(in->n, PS_TYPE_F32);
+        for (i = 0; i < in->n; i++) {
+            tmp->data.F32[i] = (float)in->data.F64[i];
+        }
+    } else if (in->type.type == PS_TYPE_F32) {
+        // do nothing
+    } else {
+        psAbort(__func__, "unsupported vector type 0x%x\n", in->type.type);
+    }
+    return (tmp);
+}
+
+/******************************************************************************
+psVectorStats(myVector, maskVector, maskVal, stats): this is the public API
+function which calls the above private stats functions based on what bits
+were set in stats->options.
+ 
+Inputs
+    myVector
+    maskVector
+    maskVal
+    stats
+Returns
+    The stats structure.
+ 
+NOTE: The current strategy is to implement everything assuming that all
+input data is of type PS_TYPE_F32.  Once the basic code is in place, we will
+macro-ize everything and add PS_TYPE_U16 and PS_TYPE_F64.
+ *****************************************************************************/
+psStats* psVectorStats(psStats* stats,
+                       psVector* in,
+                       psVector* mask,
+                       unsigned int maskVal)
+{
+    psVector* inF32;
+    int mustFreeTmp = 1;
+
+    // NOTE: Verify that this is the correct action.
+    if (in == NULL) {
+        return (stats);
+    }
+    if (stats == NULL) {
+        return (NULL);
+    }
+
+    inF32 = p_psConvertToF32(stats, in, mask, maskVal);
+    if (inF32 == NULL) {
+        inF32 = in;
+        mustFreeTmp = 0;
+    }
+    // XXX: Should we abort if (stats->min == stats->max)?
+    if ((stats->options & PS_STAT_USE_RANGE) && (stats->min >= stats->max)) {
+        psAbort(__func__, "psVectorStats() called with range: %f to %f\n", stats->min, stats->max);
+    }
+
+    if (mask != NULL) {
+        PS_CHECK_VECTOR_SIZE_EQUAL_RETURN_NULL(mask, in);
+        PS_CHECK_VECTOR_TYPE_RETURN_NULL(mask, PS_TYPE_U8);
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_MEAN) {
+        p_psVectorSampleMean(inF32, mask, maskVal, stats);
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_MEDIAN) {
+        p_psVectorSampleMedian(inF32, mask, maskVal, stats);
+    }
+    // ************************************************************************
+    // NOTE: The Stdev calculation requires the mean.  Should we assume the
+    // mean has already been calculated? Or should we always calculate it?
+    if (stats->options & PS_STAT_SAMPLE_STDEV) {
+        p_psVectorSampleMean(inF32, mask, maskVal, stats);
+        p_psVectorSampleStdev(inF32, mask, maskVal, stats);
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_SAMPLE_QUARTILE) {
+        p_psVectorSampleQuartiles(inF32, mask, maskVal, stats);
+    }
+    // Since the various robust stats quantities share much computation, they
+    // are grouped together in a single private function:
+    // p_psVectorRobustStats()
+    if ((stats->options & PS_STAT_ROBUST_MEAN) ||
+            (stats->options & PS_STAT_ROBUST_MEDIAN) ||
+            (stats->options & PS_STAT_ROBUST_MODE) ||
+            (stats->options & PS_STAT_ROBUST_STDEV) || (stats->options & PS_STAT_ROBUST_QUARTILE)) {
+        p_psVectorRobustStats(inF32, mask, maskVal, stats);
+    }
+
+    if ((stats->options & PS_STAT_CLIPPED_MEAN) || (stats->options & PS_STAT_CLIPPED_STDEV)) {
+        p_psVectorClippedStats(inF32, mask, maskVal, stats);
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_MAX) {
+        p_psVectorMax(inF32, mask, maskVal, stats);
+    }
+    // ************************************************************************
+    if (stats->options & PS_STAT_MIN) {
+        p_psVectorMin(inF32, mask, maskVal, stats);
+    }
+
+    if (mustFreeTmp == 1) {
+        psFree(inF32);
+    }
+    return (stats);
+}
Index: /branches/rel3/psLib/src/math/psStats.h
===================================================================
--- /branches/rel3/psLib/src/math/psStats.h	(revision 2163)
+++ /branches/rel3/psLib/src/math/psStats.h	(revision 2163)
@@ -0,0 +1,183 @@
+
+/** @file  psStats.h
+ *  \brief basic statistical operations
+ *  @ingroup Stats
+ *
+ *  This file will hold the definition of the histogram and stats data
+ *  structures.  It also contains prototypes for procedures which operate
+ *  on those data structures.
+ *
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.31 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-06 20:07:04 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_STATS_H)
+#define PS_STATS_H
+
+#include "psVector.h"
+
+/// @addtogroup Stats
+/// @{
+
+/******************************************************************************
+    Statistical functions and data structures.
+ *****************************************************************************/
+
+/** enumeration of statistical calculation options
+ *
+ *  @see psStats, psVectorStats, psImageStats
+ */
+// XXX: Is PS_STAT_ROBUST_FOR_SAMPLE obsolete?
+typedef enum {
+    PS_STAT_SAMPLE_MEAN = 0x000001,
+    PS_STAT_SAMPLE_MEDIAN = 0x000002,
+    PS_STAT_SAMPLE_STDEV = 0x000004,
+    PS_STAT_SAMPLE_QUARTILE = 0x000008,
+    PS_STAT_ROBUST_MEAN = 0x000010,
+    PS_STAT_ROBUST_MEDIAN = 0x000020,
+    PS_STAT_ROBUST_MODE = 0x000040,
+    PS_STAT_ROBUST_STDEV = 0x000080,
+    PS_STAT_ROBUST_QUARTILE = 0x000100,
+    PS_STAT_CLIPPED_MEAN = 0x000200,
+    PS_STAT_CLIPPED_STDEV = 0x000400,
+    PS_STAT_MAX =  0x000800,
+    PS_STAT_MIN =  0x001000,
+    PS_STAT_USE_RANGE =  0x002000,
+    PS_STAT_USE_BINSIZE = 0x004000,
+    PS_STAT_ROBUST_FOR_SAMPLE = 0x008000
+} psStatsOptions;
+
+/** This is the generic statistics structure.  It contails the data members
+    for the various statistic values.  It also contains the options member to
+    specifiy which statistics should be calculated. */
+typedef struct
+{
+    double sampleMean;          ///< formal mean of sample
+    double sampleMedian;        ///< formal median of sample
+    double sampleStdev;         ///< standard deviation of sample
+    double sampleUQ;            ///< upper quartile of sample
+    double sampleLQ;            ///< lower quartile of sample
+    double robustMean;          ///< robust mean of array
+    double robustMedian;        ///< robust median of array
+    double robustMode;          ///< Robust mode of array
+    double robustStdev;         ///< robust standard deviation of array
+    double robustUQ;            ///< robust upper quartile
+    double robustLQ;            ///< robust lower quartile
+    int robustN50;              ///<
+    int robustNfit;             ///<
+    double clippedMean;         ///< Nsigma clipped mean
+    double clippedStdev;        ///< standard deviation after clipping
+    int clippedNvalues;         ///< ???
+    double clipSigma;           ///< Nsigma used for clipping; user input
+    int clipIter;               ///< Number of clipping iterations; user input
+    double min;                 ///< minimum data value in array
+    double max;                 ///< maximum data value in array
+    double binsize;             ///<
+    psStatsOptions options;     ///< bitmask of calculated values
+}
+psStats;
+
+/** Performs statistical calculations on a vector.
+ *
+ *  @return psStats*    the statistical results as specified by stats->options
+ */
+psStats* psVectorStats(
+    psStats* stats,    ///< stats structure defines stats to be calculated and how
+    psVector* in,    ///< Vector to be analysed: must be F32
+    psVector* mask,    ///< Ignore elements where (maskVector & maskVal) != 0: must be INT or NULL
+    unsigned int maskVal    ///< Only mask elements with one of these bits set in maskVector
+);
+
+/** Allocator of the psStats structure.
+ *
+ *  @return psStats*    A new psStats struct with the options member set to the
+ *                      value given.
+ */
+psStats* psStatsAlloc(
+    psStatsOptions options             ///< Statistics to calculate
+);
+
+/******************************************************************************
+    Histogram functions and data structures.
+ *****************************************************************************/
+
+/** The basic histogram structure which contains bounds and bins.
+ *
+ *  In this structure, the vector bounds specifies the boundaries of the 
+ *  histogram bins, and must of type psF32, while nums specifies the number 
+ *  of entries in the bin, and must of type psU32. The value of bounds.n must 
+ *  therefore be 1 greater than than nums.n. The two values minNum and maxNum 
+ *  are the number of data values which fell below the lower limit bound or 
+ *  above the upper limit bound, respectively.
+ */
+typedef struct
+{
+    psVector* bounds;                  ///< Bounds for the bins (type F32)
+    psVector* nums;                    ///< Number in each of the bins (INT)
+    int minNum;                        ///< Number below the minimum
+    int maxNum;                        ///< Number above the maximum
+    bool uniform;                      ///< Is it a uniform distribution?
+}
+psHistogram;
+
+/** Allocator for psHistogram where the bounds of the bins are implicitly
+ *  specified through simply specifying an upper and lower limit along with 
+ *  the size of the bins. 
+ *
+ *  @return psHistogram*    Newly allocated psHistogram
+ */
+psHistogram* psHistogramAlloc(
+    float lower,                       ///< Lower limit for the bins
+    float upper,                       ///< Upper limit for the bins
+    int n                              ///< Number of bins
+);
+
+/** Allocator for psHistogram where the bounds of the bins are explicitly
+ *  specified. 
+ *
+ *  @return psHistogram*    Newly allocated psHistogram
+ */
+psHistogram* psHistogramAllocGeneric(
+    const psVector* restrict bounds    ///< Bounds for the bins
+);
+
+/** Calculate a histogram
+ *
+ *  The following function populates the histogram bins from the specified 
+ *  vector (in). It alters and returns the histogram out structure. The input
+ *  vector may be of types psU8, psU16, psF32, psF64.
+ *
+ *  @return psHistogram*   histogram result
+ */
+psHistogram* psVectorHistogram(
+    psHistogram* out,                  ///< Histogram data
+    const psVector* restrict in,       ///< Vector to analyse
+    const psVector* restrict mask,     ///< Mask dat for input vector
+    unsigned int maskVal               ///< Mask value
+);
+
+/** Extracts the statistic value specified by stats->options.
+ *
+ *  @return bool    If more than one statistic result is set in stats->options,
+ *                  false is returned and the value parameter is not set, 
+ *                  otherwise true is returned.
+ */
+bool p_psGetStatValue(
+    const psStats* stats,
+    ///< the statistic struct to operate on
+
+    double *value
+    ///< if return is true, this is set to the specified statistic value by stats->options
+);
+
+
+void p_psNormalizeVector(psVector* myData);
+
+void p_psNormalizeVectorF64(psVector* myData);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/mathtypes/psImage.c
===================================================================
--- /branches/rel3/psLib/src/mathtypes/psImage.c	(revision 2163)
+++ /branches/rel3/psLib/src/mathtypes/psImage.c	(revision 2163)
@@ -0,0 +1,697 @@
+
+/** @file  psImage.c
+ *
+ *  @brief Contains basic image definitions and operations.
+ *
+ *  This file defines the basic type for an image struct and functions useful
+ *  in manupulating images.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.50 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 01:22:59 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ *  That is the routine used to generate matrices.
+ */
+
+#include <string.h>
+#include <math.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psImage.h"
+
+#include "psImageErrors.h"
+
+static void imageFree(psImage* image);
+
+psImage* psImageAlloc(unsigned int numCols,
+                      unsigned int numRows,
+                      const psElemType type)
+{
+    int area = 0;
+    int elementSize = PSELEMTYPE_SIZEOF(type);  // element size in bytes
+    int rowSize = numCols * elementSize;        // row size in bytes.
+
+    area = numCols * numRows;
+
+    if (area < 1) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageAlloc",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psImage_AREA_NEGATIVE,
+                   numRows, numCols);
+        return NULL;
+    }
+
+    psImage* image = (psImage* ) psAlloc(sizeof(psImage));
+
+    p_psMemSetDeallocator(image, (psFreeFcn) imageFree);
+
+    image->data.V = psAlloc(sizeof(void *) * numRows);
+
+    image->rawDataBuffer = psAlloc(area * elementSize);
+
+    // set the row pointers.
+    image->data.V[0] = image->rawDataBuffer;
+    for (int i = 1; i < numRows; i++) {
+        image->data.V[i] = (void *)((int8_t *) image->data.V[i - 1] + rowSize);
+    }
+
+    *(int *)&image->col0 = 0;
+    *(int *)&image->row0 = 0;
+    *(unsigned int *)&image->numCols = numCols;
+    *(unsigned int *)&image->numRows = numRows;
+    *(psDimen* ) & image->type.dimen = PS_DIMEN_IMAGE;
+    *(psElemType* ) & image->type.type = type;
+    image->parent = NULL;
+    image->children = NULL;
+
+    return image;
+}
+
+static void imageFree(psImage* image)
+{
+    if (image == NULL) {
+        return;
+    }
+
+    if (image->type.type == PS_TYPE_PTR) {
+        // 2-D array of pointers -- must dereference elements
+        unsigned int oldNumRows = image->numRows;
+        unsigned int oldNumCols = image->numCols;
+        psPTR* rowPtr;
+
+        for (unsigned int row = 0; row < oldNumRows; row++) {
+            rowPtr = image->data.PTR[row];
+            for (unsigned int col = 0; col < oldNumCols; col++) {
+                psMemDecrRefCounter(rowPtr[col]);
+            }
+        }
+    }
+
+    if (image->parent != NULL) {
+        psArrayRemove(image->parent->children,image);
+        image->parent = NULL;
+    }
+
+    psImageFreeChildren(image);
+
+    psFree(image->rawDataBuffer);
+    psFree(image->data.V);
+}
+
+psImage* psImageRecycle(psImage* old,
+                        unsigned int numCols,
+                        unsigned int numRows,
+                        const psElemType type)
+{
+    int elementSize = PSELEMTYPE_SIZEOF(type);  // element size in bytes
+    int rowSize = numCols * elementSize;        // row size in bytes.
+
+    if (old == NULL) {
+        old = psImageAlloc(numCols, numRows, type);
+        return old;
+    }
+
+    if (old->type.dimen != PS_DIMEN_IMAGE) {
+        psFree(old);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageRecycle",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImage_NOT_AN_IMAGE);
+        return NULL;
+    }
+
+    if (old->type.type == PS_TYPE_PTR) {
+        // 2-D array of pointers -- must
+        // dereference
+        unsigned int oldNumRows = old->numRows;
+        unsigned int oldNumCols = old->numCols;
+        psPTR* rowPtr;
+
+        for (unsigned int row = 0; row < oldNumRows; row++) {
+            rowPtr = old->data.PTR[row];
+            for (unsigned int col = 0; col < oldNumCols; col++) {
+                psMemDecrRefCounter(rowPtr[col]);
+                rowPtr[col] = NULL;
+            }
+        }
+    }
+
+    /* image already the right size/type? */
+    if (numCols == old->numCols && numRows == old->numRows &&
+            type == old->type.type) {
+        return old;
+    }
+    // Resize the image buffer
+    old->rawDataBuffer = psRealloc(old->data.V[0],
+                                   numCols * numRows * elementSize);
+    old->data.V = (void **)psRealloc(old->data.V, numRows * sizeof(void *));
+
+    // recreate the row pointers
+    old->data.V[0] = old->rawDataBuffer;
+    for (int i = 1; i < numRows; i++) {
+        old->data.V[i] = (void *)((int8_t *) old->data.V[i - 1] + rowSize);
+    }
+
+    *(unsigned int *)&old->numCols = numCols;
+    *(unsigned int *)&old->numRows = numRows;
+    *(psElemType* ) & old->type.type = type;
+
+    return old;
+}
+
+psImage* psImageCopy(psImage* restrict output,
+                     const psImage* input,
+                     psElemType type)
+{
+    psElemType inDatatype;
+    int elementSize;
+    int elements;
+    int numRows;
+    int numCols;
+
+    if (input == NULL || input->data.V == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCopy",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        psFree(output);
+        return NULL;
+    }
+
+    if (input == output) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCopy",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psImage_INPLACE_NOTSUPPORTED);
+        psFree(output);
+        return NULL;
+    }
+
+    if (input->type.dimen != PS_DIMEN_IMAGE) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCopy",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImage_NOT_AN_IMAGE);
+        psFree(output);
+        return NULL;
+    }
+
+    inDatatype = input->type.type;
+    numRows = input->numRows;
+    numCols = input->numCols;
+    elements = numRows * numCols;
+    elementSize = PSELEMTYPE_SIZEOF(inDatatype);
+
+    if (inDatatype == PS_TYPE_PTR || type == PS_TYPE_PTR) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCopy",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                   PS_TYPE_PTR_NAME);
+        psFree(output);
+        return NULL;
+    }
+
+    output = psImageRecycle(output, numCols, numRows, type);
+
+    // cover the trival case of copy of the same
+    // datatype.
+    if (type == inDatatype) {
+        for (int row=0;row<numRows;row++) {
+            memcpy(output->data.V[row], input->data.V[row], elementSize * numCols);
+        }
+        return output;
+    }
+
+    #define PSIMAGE_ELEMENT_COPY(IN,INTYPE,OUT,OUTTYPE,ELEMENTS) { \
+        ps##INTYPE *in; \
+        ps##OUTTYPE *out; \
+        for(int row=0;row<numRows;row++) { \
+            in = IN->data.INTYPE[row]; \
+            out = OUT->data.OUTTYPE[row]; \
+            for (int col=0;col<numCols;col++) { \
+                *(out++) = *(in++); \
+            } \
+        } \
+    }
+
+    #define PSIMAGE_COPY_CASE(OUT,OUTTYPE) { \
+        switch (inDatatype) { \
+        case PS_TYPE_S8: \
+            PSIMAGE_ELEMENT_COPY(input,S8,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_S16: \
+            PSIMAGE_ELEMENT_COPY(input,S16,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_S32: \
+            PSIMAGE_ELEMENT_COPY(input,S32,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_S64: \
+            PSIMAGE_ELEMENT_COPY(input,S64,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_U8: \
+            PSIMAGE_ELEMENT_COPY(input,U8,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_U16: \
+            PSIMAGE_ELEMENT_COPY(input,U16,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_U32: \
+            PSIMAGE_ELEMENT_COPY(input,U32,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_U64: \
+            PSIMAGE_ELEMENT_COPY(input,U64,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_F32: \
+            PSIMAGE_ELEMENT_COPY(input,F32,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_F64: \
+            PSIMAGE_ELEMENT_COPY(input,F64,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_C32: \
+            PSIMAGE_ELEMENT_COPY(input,C32,OUT,OUTTYPE,elements); \
+            break; \
+        case PS_TYPE_C64: \
+            PSIMAGE_ELEMENT_COPY(input,C64,OUT,OUTTYPE,elements); \
+            break; \
+        default: \
+            break; \
+        } \
+    }
+
+    switch (type) {
+    case PS_TYPE_S8:
+        PSIMAGE_COPY_CASE(output, S8);
+        break;
+    case PS_TYPE_S16:
+        PSIMAGE_COPY_CASE(output, S16);
+        break;
+    case PS_TYPE_S32:
+        PSIMAGE_COPY_CASE(output, S32);
+        break;
+    case PS_TYPE_S64:
+        PSIMAGE_COPY_CASE(output, S64);
+        break;
+    case PS_TYPE_U8:
+        PSIMAGE_COPY_CASE(output, U8);
+        break;
+    case PS_TYPE_U16:
+        PSIMAGE_COPY_CASE(output, U16);
+        break;
+    case PS_TYPE_U32:
+        PSIMAGE_COPY_CASE(output, U32);
+        break;
+    case PS_TYPE_U64:
+        PSIMAGE_COPY_CASE(output, U64);
+        break;
+    case PS_TYPE_F32:
+        PSIMAGE_COPY_CASE(output, F32);
+        break;
+    case PS_TYPE_F64:
+        PSIMAGE_COPY_CASE(output, F64);
+        break;
+    case PS_TYPE_C32:
+        PSIMAGE_COPY_CASE(output, C32);
+        break;
+    case PS_TYPE_C64:
+        PSIMAGE_COPY_CASE(output, C64);
+        break;
+    default: {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCopy",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                       typeStr);
+            psFree(output);
+
+            break;
+        }
+    }
+    return output;
+}
+
+int psImageFreeChildren(psImage* image)
+{
+    int numFreed = 0;
+
+    if (image == NULL) {
+        return numFreed;
+    }
+
+    if (image->children != NULL) {
+        psImage** children = (psImage**)image->children->data;
+        numFreed = image->children->n;
+
+        // orphan the children first
+        // (so psFree doesn't try to modify the parent's children array while I'm using it)
+        for (int i=0;i<numFreed;i++) {
+            children[i]->parent = NULL;
+        }
+
+        psFree(image->children);
+        image->children = NULL;
+    }
+
+    return numFreed;
+}
+
+/*****************************************************************************
+p_psImagePixelInterpolation(image, x, y): this routine takes as input an
+image and coordinates (x, y) and produces as output the corresponding pixel
+value at the those coordinates.  For fractional corrdinates (x, y), 2-D
+linear interpolation is performed on the image.
+ *****************************************************************************/
+psC64 psImagePixelInterpolate(const psImage* input,
+                              float x,
+                              float y,
+                              const psImage* mask,
+                              unsigned int maskVal,
+                              psC64 unexposedValue,
+                              psImageInterpolateMode mode)
+{
+
+    if (input == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImagePixelInterpolate",
+                   PS_ERR_BAD_PARAMETER_NULL,true,
+                   PS_ERRORTEXT_psImage_IMAGE_NULL);
+        return unexposedValue;
+    }
+
+    #define PSIMAGE_PIXEL_INTERPOLATE_CASE(TYPE)                     \
+case PS_TYPE_##TYPE:                                                 \
+    switch (mode) {                                                  \
+    case PS_INTERPOLATE_FLAT:                                        \
+        return p_psImagePixelInterpolateFLAT_##TYPE(                 \
+                input,                                               \
+                x,                                                   \
+                y,                                                   \
+                mask,                                                \
+                maskVal,                                             \
+                unexposedValue);                                     \
+        break;                                                       \
+    case PS_INTERPOLATE_BILINEAR:                                    \
+        return p_psImagePixelInterpolateBILINEAR_##TYPE(             \
+                input,                                               \
+                x,                                                   \
+                y,                                                   \
+                mask,                                                \
+                maskVal,                                             \
+                unexposedValue);                                     \
+        break;                                                       \
+    default:                                                         \
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psImagePixelInterpolate",    \
+                   PS_ERR_BAD_PARAMETER_VALUE,true,                  \
+                   PS_ERRORTEXT_psImage_INTERPOLATE_METHOD_INVALID,  \
+                   mode);                                            \
+    }                                                                \
+    break
+
+    switch (input->type.type) {
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(U8);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(U16);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(U32);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(U64);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(S8);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(S16);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(S32);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(S64);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(F32);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(F64);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(C32);
+        PSIMAGE_PIXEL_INTERPOLATE_CASE(C64);
+    default: {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,input->type.type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImagePixelInterpolate",
+                       PS_ERR_BAD_PARAMETER_TYPE,true,
+                       PS_ERRORTEXT_psImage_IMAGE_TYPE_UNSUPPORTED,
+                       typeStr);
+        }
+    }
+
+    return unexposedValue;
+}
+
+#define PSIMAGE_PIXEL_INTERPOLATE_FLAT(TYPE) \
+inline psF64 p_psImagePixelInterpolateFLAT_##TYPE(const psImage* input, \
+        float x, \
+        float y, \
+        const psImage* mask, \
+        unsigned int maskVal, \
+        psF64 unexposedValue) \
+{ \
+    int intX = (int) round((psF64)(x) - 0.5 + FLT_EPSILON); \
+    int intY = (int) round((psF64)(y) - 0.5 + FLT_EPSILON); \
+    int lastX = input->numCols - 1; \
+    int lastY = input->numRows - 1; \
+    \
+    if ((intX < 0) || \
+            (intX > lastX) || \
+            (intY < 0) || \
+            (intY > lastY) || \
+            ( (mask!=NULL) && \
+              ((mask->data.PS_TYPE_MASK_DATA[intY][intX] & maskVal) != 0) ) ) { \
+        return unexposedValue; \
+    } \
+    \
+    return input->data.TYPE[intY][intX]; \
+}
+
+#define PSIMAGE_PIXEL_INTERPOLATE_FLAT_COMPLEX(TYPE) \
+inline psC64 p_psImagePixelInterpolateFLAT_##TYPE(const psImage* input, \
+        float x, \
+        float y, \
+        const psImage* mask, \
+        unsigned int maskVal, \
+        psC64 unexposedValue) \
+{ \
+    int intX = (int) round((psF64)(x) - 0.5); \
+    int intY = (int) round((psF64)(y) - 0.5); \
+    int lastX = input->numCols - 1; \
+    int lastY = input->numRows - 1; \
+    \
+    if ((intX < 0) || \
+            (intX > lastX) || \
+            (intY < 0) || \
+            (intY > lastY) || \
+            ( (mask!=NULL) && \
+              ((mask->data.PS_TYPE_MASK_DATA[intY][intX] & maskVal) != 0) ) ) { \
+        return unexposedValue; \
+    } \
+    \
+    return input->data.TYPE[intY][intX]; \
+}
+
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(U8)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(U16)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(U32)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(U64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(S8)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(S16)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(S32)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(S64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(F32)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT(F64)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT_COMPLEX(C32)
+PSIMAGE_PIXEL_INTERPOLATE_FLAT_COMPLEX(C64)
+
+#define PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(TYPE) \
+inline psF64 p_psImagePixelInterpolateBILINEAR_##TYPE(const psImage* input, \
+        float x, \
+        float y, \
+        const psImage* mask, \
+        unsigned int maskVal, \
+        psF64 unexposedValue) \
+{ \
+    double floorX = floor((psF64)(x) - 0.5); \
+    double floorY = floor((psF64)(y) - 0.5); \
+    psF64 fracX = x - 0.5 - floorX; \
+    psF64 fracY = y - 0.5 - floorY; \
+    int intFloorX = (int) floorX; \
+    int intFloorY = (int) floorY; \
+    int lastX = input->numCols - 1; \
+    int lastY = input->numRows - 1; \
+    ps##TYPE V00; \
+    ps##TYPE V01; \
+    ps##TYPE V10; \
+    ps##TYPE V11; \
+    bool valid00 = false; \
+    bool valid01 = false; \
+    bool valid10 = false; \
+    bool valid11 = false; \
+    \
+    if (intFloorY >= 0 && intFloorY <= lastY) { \
+        if (intFloorX >= 0 && intFloorX <= lastX) { \
+            V00 = input->data.TYPE[intFloorY][intFloorX]; \
+            valid00 = (mask == NULL) || \
+                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY][intFloorX] & maskVal) == 0); \
+        } \
+        if (intFloorX >= -1 && intFloorX < lastX) { \
+            V10 = input->data.TYPE[intFloorY][intFloorX+1]; \
+            valid10 = (mask == NULL) || \
+                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY][intFloorX+1] & maskVal) == 0); \
+        } \
+    } \
+    if (intFloorY >= -1 && intFloorY < lastY) { \
+        if (intFloorX >= 0 && intFloorX <= lastX) { \
+            V01 = input->data.TYPE[intFloorY+1][intFloorX]; \
+            valid01 = (mask == NULL) || \
+                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY+1][intFloorX] & maskVal) == 0); \
+        } \
+        if (intFloorX >= -1 && intFloorX < lastX) { \
+            V11 = input->data.TYPE[intFloorY+1][intFloorX+1]; \
+            valid11 = (mask == NULL) || \
+                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY+1][intFloorX+1] & maskVal) == 0); \
+        } \
+    } \
+    \
+    /* cover likely case of all pixels being valid more efficiently */  \
+    if (valid00 && valid10 && valid01 && valid11) { \
+        /* formula from the ADD */ \
+        psF64 rx = V00 + (V10-V00)*fracX; \
+        return (rx + (V01 + (V11 - V01) * fracX - rx) * fracY); \
+    } \
+    \
+    /* OK, at least one pixel is not valid - need to do it piecemeal */ \
+    \
+    psF64 V0; \
+    bool valid0 = true; \
+    if (valid00 && valid10) { \
+        V0 = V00*(1-fracX)+V10*fracX; \
+    } else if (valid00) { \
+        V0 = V00; \
+    } else if (valid10) { \
+        V0 = V10; \
+    } else { \
+        valid0 = false; \
+    } \
+    \
+    psF64 V1; \
+    bool valid1 = true; \
+    if (valid01 && valid11) { \
+        V1 = V01*(1-fracX)+V11*fracX; \
+    } else if (valid01) { \
+        V1 = V01; \
+    } else if (valid11) { \
+        V1 = V11; \
+    } else { \
+        valid1 = false; \
+    } \
+    \
+    if (valid0 && valid1) { \
+        return ( V0*(1-fracY) + V1*fracY ); \
+    } else if (valid0) { \
+        return V0; \
+    } else if (valid1) { \
+        return V1; \
+    } \
+    \
+    return unexposedValue; \
+}
+
+#define PSIMAGE_PIXEL_INTERPOLATE_BILINEAR_COMPLEX(TYPE) \
+inline psC64 p_psImagePixelInterpolateBILINEAR_##TYPE(const psImage* input, \
+        float x, \
+        float y, \
+        const psImage* mask, \
+        unsigned int maskVal, \
+        psC64 unexposedValue) \
+{ \
+    double floorX = floor((psF64)(x) - 0.5); \
+    double floorY = floor((psF64)(y) - 0.5); \
+    psF64 fracX = x - 0.5 - floorX; \
+    psF64 fracY = y - 0.5 - floorY; \
+    int intFloorX = (int) floorX; \
+    int intFloorY = (int) floorY; \
+    int lastX = input->numCols - 1; \
+    int lastY = input->numRows - 1; \
+    ps##TYPE V00; \
+    ps##TYPE V01; \
+    ps##TYPE V10; \
+    ps##TYPE V11; \
+    bool valid00 = false; \
+    bool valid01 = false; \
+    bool valid10 = false; \
+    bool valid11 = false; \
+    \
+    if (intFloorY >= 0 && intFloorY <= lastY) { \
+        if (intFloorX >= 0 && intFloorX <= lastX) { \
+            V00 = input->data.TYPE[intFloorY][intFloorX]; \
+            valid00 = (mask == NULL) || \
+                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY][intFloorX] & maskVal) == 0); \
+        } \
+        if (intFloorX >= -1 && intFloorX < lastX) { \
+            V10 = input->data.TYPE[intFloorY][intFloorX+1]; \
+            valid10 = (mask == NULL) || \
+                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY][intFloorX+1] & maskVal) == 0); \
+        } \
+    } \
+    if (intFloorY >= -1 && intFloorY < lastY) { \
+        if (intFloorX >= 0 && intFloorX <= lastX) { \
+            V01 = input->data.TYPE[intFloorY+1][intFloorX]; \
+            valid01 = (mask == NULL) || \
+                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY+1][intFloorX] & maskVal) == 0); \
+        } \
+        if (intFloorX >= -1 && intFloorX < lastX) { \
+            V11 = input->data.TYPE[intFloorY+1][intFloorX+1]; \
+            valid11 = (mask == NULL) || \
+                      ((mask->data.PS_TYPE_MASK_DATA[intFloorY+1][intFloorX+1] & maskVal) == 0); \
+        } \
+    } \
+    \
+    /* cover likely case of all pixels being valid */  \
+    if (valid00 && valid10 && valid01 && valid11) { \
+        /* formula from the ADD */ \
+        psC64 rx = V00 + (V10-V00)*fracX; \
+        return (rx + (V01 + (V11 - V01) * fracX - rx) * fracY); \
+    } \
+    \
+    /* OK, at least one pixel is not valid - need to do it piecemeal */ \
+    \
+    psC64 V0; \
+    bool valid0 = true; \
+    if (valid00 && valid10) { \
+        V0 = V00*(1-fracX)+V10*fracX; \
+    } else if (valid00) { \
+        V0 = V00; \
+    } else if (valid10) { \
+        V0 = V10; \
+    } else { \
+        valid0 = false; \
+    } \
+    \
+    psC64 V1; \
+    bool valid1 = true; \
+    if (valid01 && valid11) { \
+        V0 = V01*(1-fracX)+V11*fracX; \
+    } else if (valid01) { \
+        V0 = V01; \
+    } else if (valid11) { \
+        V0 = V11; \
+    } else { \
+        valid1 = false; \
+    } \
+    \
+    if (valid0 && valid1) { \
+        return ( V0*(1-fracY) + V1*fracY ); \
+    } else if (valid0) { \
+        return V0; \
+    } else if (valid1) { \
+        return V1; \
+    } \
+    \
+    return unexposedValue; \
+}
+
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U8)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U16)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U32)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(U64)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S8)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S16)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S32)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(S64)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F32)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR(F64)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR_COMPLEX(C32)
+PSIMAGE_PIXEL_INTERPOLATE_BILINEAR_COMPLEX(C64)
Index: /branches/rel3/psLib/src/mathtypes/psImage.h
===================================================================
--- /branches/rel3/psLib/src/mathtypes/psImage.h	(revision 2163)
+++ /branches/rel3/psLib/src/mathtypes/psImage.h	(revision 2163)
@@ -0,0 +1,190 @@
+/** @file  psImage.h
+ *
+ *  @brief Contains basic image definitions and operations
+ *
+ *  This file defines the basic type for an image struct and functions useful
+ *  in manupulating images.
+ *
+ *  @ingroup Image
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.41 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 01:22:59 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#ifndef PS_IMAGE_H
+#define PS_IMAGE_H
+
+#include <complex.h>
+
+#include "psType.h"
+#include "psArray.h"
+
+/// @addtogroup Image
+/// @{
+
+/** enumeration of options in interpolation
+ *
+ */
+typedef enum {
+    PS_INTERPOLATE_FLAT = 1,           ///< 'flat' interpolation (nearest pixel)
+    PS_INTERPOLATE_BILINEAR,           ///< bi-linear interpolation
+    PS_INTERPOLATE_BICUBIC,            ///< bi-cubic interpolation
+    PS_INTERPOLATE_SINC,               ///< sinc interpolation
+    PS_INTERPOLATE_NUM_MODES           ///< end-marker of list of modes; not a valid interpolation mode
+} psImageInterpolateMode;
+
+/** Basic image data structure.
+ *
+ * Struct for maintaining image data of varying types. It also contains
+ * information about image size, parent images and children images.
+ *
+ */
+typedef struct psImage
+{
+    const psType type;                 ///< Image data type and dimension.
+    const unsigned int numCols;        ///< Number of columns in image
+    const unsigned int numRows;        ///< Number of rows in image.
+    const int col0;                    ///< Column position relative to parent.
+    const int row0;                    ///< Row position relative to parent.
+
+    union {
+        psU8**  U8;                    ///< Unsigned 8-bit integer data.
+        psU16** U16;                   ///< Unsigned 16-bit integer data.
+        psU32** U32;                   ///< Unsigned 32-bit integer data.
+        psU64** U64;                   ///< Unsigned 64-bit integer data.
+        psS8**  S8;                    ///< Signed 8-bit integer data.
+        psS16** S16;                   ///< Signed 16-bit integer data.
+        psS32** S32;                   ///< Signed 32-bit integer data.
+        psS64** S64;                   ///< Signed 64-bit integer data.
+        psF32** F32;                   ///< Single-precision float data.
+        psF64** F64;                   ///< Double-precision float data.
+        psC32** C32;                   ///< Single-precision complex data.
+        psC64** C64;                   ///< Double-precision complex data.
+        psPTR** PTR;                   ///< Void pointers.
+        psPTR*  V;                     ///< Pointer to data.
+    } data;                            ///< Union for data types.
+    const struct psImage* parent;      ///< Parent, if a subimage.
+    psArray* children;                 ///< Children of this region.
+
+    void* rawDataBuffer;
+}
+psImage;
+
+/** Create an image of the specified size and type.
+ *
+ * Uses psLib memory allocation functions to create an image struct of the
+ * specified size and type.
+ *
+ * @return psImage* : Pointer to psImage.
+ *
+ */
+psImage* psImageAlloc(
+    unsigned int numCols,              ///< Number of rows in image.
+    unsigned int numRows,              ///< Number of columns in image.
+    const psElemType type              ///< Type of data for image.
+);
+
+/** Resize a given image to the given size/type.
+ *
+ *  @return psImage* Resized psImage.
+ *
+ */
+psImage* psImageRecycle(
+    psImage* old,                      ///< the psImage to recycle by resizing image buffer
+    unsigned int numCols,              ///< the desired number of columns in image
+    unsigned int numRows,              ///< the desired number of rows in image
+    const psElemType type              ///< the desired datatype of the image
+);
+
+/** Makes a copy of a psImage
+ *
+ * @return psImage* Copy of the input psImage.  This may not be equal to the
+ * output parameter
+ *
+ */
+psImage* psImageCopy(
+    psImage* restrict output,          ///< if not NULL, a psImage that could be recycled.
+    const psImage* input,              ///< the psImage to copy
+    psElemType type                    ///< the desired datatype of the returned copy
+);
+
+/** Frees all children of a psImage.
+ *
+ *  @return int      Number of children freed.
+ *
+ */
+int psImageFreeChildren(
+    psImage* image                     ///< psImage in which all children shall be deallocated
+);
+
+/** Interpolate image pixel value given floating point coordinates.
+ *
+ *  @return psF32    Pixel value interpolated from image or unexposedValue if
+ *                   given x,y doesn't coorespond to a valid image location
+ */
+psC64 psImagePixelInterpolate(
+    const psImage* input,              ///< input image for interpolation
+    float x,                           ///< column location to derive value of
+    float y,                           ///< row location ot derive value of
+    const psImage* mask,               ///< if not NULL, the mask of the input image
+    unsigned int maskVal,              ///< the mask value
+    psC64 unexposedValue,              ///< return value if x,y location is not in image.
+    psImageInterpolateMode mode        ///< interpolation mode
+);
+
+#define p_psImagePixelInterpolateFcns(TYPE) \
+inline psF64 p_psImagePixelInterpolateFLAT_##TYPE( \
+        const psImage* input,          /**< input image for interpolation */ \
+        float x,                       /**< column location to derive value of */ \
+        float y,                       /**< row location ot derive value of */ \
+        const psImage* mask,           /**< if not NULL, the mask of the input image */ \
+        unsigned int maskVal,          /**< the mask value */ \
+        psF64 unexposedValue           /**< return value if x,y location is not in image. */ \
+                                                 ); \
+inline psF64 p_psImagePixelInterpolateBILINEAR_##TYPE( \
+        const psImage* input,          /**< input image for interpolation */ \
+        float x,                       /**< column location to derive value of */ \
+        float y,                       /**< row location ot derive value of */ \
+        const psImage* mask,           /**< if not NULL, the mask of the input image */ \
+        unsigned int maskVal,          /**< the mask value */ \
+        psF64 unexposedValue           /**< return value if x,y location is not in image. */ \
+                                                     );
+
+#define p_psImagePixelInterpolateComplexFcns(TYPE) \
+inline psC64 p_psImagePixelInterpolateFLAT_##TYPE( \
+        const psImage* input,          /**< input image for interpolation */ \
+        float x,                       /**< column location to derive value of */ \
+        float y,                       /**< row location ot derive value of */ \
+        const psImage* mask,           /**< if not NULL, the mask of the input image */ \
+        unsigned int maskVal,          /**< the mask value */ \
+        psC64 unexposedValue           /**< return value if x,y location is not in image. */ \
+                                                 ); \
+inline psC64 p_psImagePixelInterpolateBILINEAR_##TYPE( \
+        const psImage* input,          /**< input image for interpolation */ \
+        float x,                       /**< column location to derive value of */ \
+        float y,                       /**< row location ot derive value of */ \
+        const psImage* mask,           /**< if not NULL, the mask of the input image */ \
+        unsigned int maskVal,          /**< the mask value */ \
+        psC64 unexposedValue           /**< return value if x,y location is not in image. */ \
+                                                     );
+
+p_psImagePixelInterpolateFcns(U8)
+p_psImagePixelInterpolateFcns(U16)
+p_psImagePixelInterpolateFcns(U32)
+p_psImagePixelInterpolateFcns(U64)
+p_psImagePixelInterpolateFcns(S8)
+p_psImagePixelInterpolateFcns(S16)
+p_psImagePixelInterpolateFcns(S32)
+p_psImagePixelInterpolateFcns(S64)
+p_psImagePixelInterpolateFcns(F32)
+p_psImagePixelInterpolateFcns(F64)
+p_psImagePixelInterpolateComplexFcns(C32)
+p_psImagePixelInterpolateComplexFcns(C64)
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/mathtypes/psScalar.c
===================================================================
--- /branches/rel3/psLib/src/mathtypes/psScalar.c	(revision 2163)
+++ /branches/rel3/psLib/src/mathtypes/psScalar.c	(revision 2163)
@@ -0,0 +1,139 @@
+/** @file  psScalar.c
+ *
+ *  @brief Contains basic scalar definitions and operations
+ *
+ *  This file defines the basic type for a scalar struct and functions useful
+ *  in manupulating scalars.
+ * *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-12 19:32:44 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psScalar.h"
+#include "psLogMsg.h"
+#include "psAbort.h"
+
+#include "psCollectionsErrors.h"
+
+psScalar* psScalarAlloc(psC64 value, psElemType dataType)
+{
+    psScalar* scalar = NULL;
+
+    // Create scalar
+    scalar = (psScalar* ) psAlloc(sizeof(psScalar));
+
+    scalar->type.dimen = PS_DIMEN_SCALAR;
+    scalar->type.type = dataType;
+
+    switch (dataType) {
+    case PS_TYPE_S8:
+        scalar->data.S8 = (psS8) value;
+        break;
+    case PS_TYPE_U8:
+        scalar->data.U8 = (psU8) value;
+        break;
+    case PS_TYPE_S16:
+        scalar->data.S16 = (psS16) value;
+        break;
+    case PS_TYPE_U16:
+        scalar->data.U16 = (psU16) value;
+        break;
+    case PS_TYPE_S32:
+        scalar->data.S32 = (psS32) value;
+        break;
+    case PS_TYPE_U32:
+        scalar->data.U32 = (psU32) value;
+        break;
+    case PS_TYPE_S64:
+        scalar->data.S64 = (psS64) value;
+        break;
+    case PS_TYPE_U64:
+        scalar->data.U64 = (psU64) value;
+        break;
+    case PS_TYPE_F32:
+        scalar->data.F32 = (psF32) value;
+        break;
+    case PS_TYPE_F64:
+        scalar->data.F64 = (psF64) value;
+        break;
+    case PS_TYPE_C32:
+        scalar->data.C32 = (psC32) value;
+        break;
+    case PS_TYPE_C64:
+        scalar->data.C64 = (psC64) value;
+        break;
+    default:
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psScalarAlloc",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psScalar_UNSUPPORTED_TYPE,
+                   dataType);
+    }
+
+    return scalar;
+}
+
+psScalar* psScalarCopy(psScalar *scalar)
+{
+    psElemType dataType;
+    psScalar *newScalar = NULL;
+
+    if (scalar == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psScalarCopy",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psScalar_COPY_NULL);
+        return NULL;
+    }
+
+    dataType = scalar->type.type;
+    switch (dataType) {
+    case PS_TYPE_S8:
+        newScalar =  psScalarAlloc(scalar->data.S8, dataType);
+        break;
+    case PS_TYPE_U8:
+        newScalar =  psScalarAlloc(scalar->data.U8, dataType);
+        break;
+    case PS_TYPE_S16:
+        newScalar =  psScalarAlloc(scalar->data.S16, dataType);
+        break;
+    case PS_TYPE_U16:
+        newScalar =  psScalarAlloc(scalar->data.U16, dataType);
+        break;
+    case PS_TYPE_S32:
+        newScalar =  psScalarAlloc(scalar->data.S32, dataType);
+        break;
+    case PS_TYPE_U32:
+        newScalar =  psScalarAlloc(scalar->data.U32, dataType);
+        break;
+    case PS_TYPE_S64:
+        newScalar =  psScalarAlloc(scalar->data.S64, dataType);
+        break;
+    case PS_TYPE_U64:
+        newScalar =  psScalarAlloc(scalar->data.U64, dataType);
+        break;
+    case PS_TYPE_F32:
+        newScalar =  psScalarAlloc(scalar->data.F32, dataType);
+        break;
+    case PS_TYPE_F64:
+        newScalar =  psScalarAlloc(scalar->data.F64, dataType);
+        break;
+    case PS_TYPE_C32:
+        newScalar =  psScalarAlloc(scalar->data.C32, dataType);
+        break;
+    case PS_TYPE_C64:
+        newScalar =  psScalarAlloc(scalar->data.C64, dataType);
+        break;
+    default:
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psScalarCopy",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psScalar_UNSUPPORTED_TYPE,
+                   dataType);
+    }
+
+    return newScalar;
+}
Index: /branches/rel3/psLib/src/mathtypes/psScalar.h
===================================================================
--- /branches/rel3/psLib/src/mathtypes/psScalar.h	(revision 2163)
+++ /branches/rel3/psLib/src/mathtypes/psScalar.h	(revision 2163)
@@ -0,0 +1,84 @@
+
+/** @file  psScalar.h
+ *
+ *  @brief Contains basic scalar definitions and operations
+ *
+ *  This file defines the basic type for a scalar struct and functions useful
+ *  in manupulating scalars.
+ *
+ *  @ingroup Scalar
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-12 19:32:44 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_SCALAR_H
+#define PS_SCALAR_H
+
+#include "psType.h"
+
+/// @addtogroup Scalar
+/// @{
+
+/** Basic scalar data structure.
+ *
+ * Struct for maintaining a scalar of frequently used primitive types.
+ *
+ */
+typedef struct
+{
+    psType type;                ///< Type of data.
+
+    union {
+        psU8 U8;                ///< Unsigned 8-bit integer data.
+        psU16 U16;              ///< Unsigned 16-bit integer data.
+        psU32 U32;              ///< Unsigned 32-bit integer data.
+        psU64 U64;              ///< Unsigned 64-bit integer data.
+        psS8 S8;                ///< Signed 8-bit integer data.
+        psS16 S16;              ///< Signed 16-bit integer data.
+        psS32 S32;              ///< Signed 32-bit integer data.
+        psS64 S64;              ///< Signed 64-bit integer data.
+        psF32 F32;              ///< Single-precision float data.
+        psF64 F64;              ///< Double-precision float data.
+        psC32 C32;              ///< Single-precision complex data.
+        psC64 C64;              ///< Double-precision complex data.
+    } data;                     ///< Union for data types.
+}
+psScalar;
+
+/*****************************************************************************/
+
+/* FUNCTION PROTOTYPES                                                       */
+
+/*****************************************************************************/
+
+/** Allocate a scalar.
+ *
+ * Uses psLib memory allocation functions to create scalar data as defined by the psType type.
+ * Accepts a complex 64 bit float for input value, as max size, but resizes according to
+ * correct type.
+ *
+ * @return psScalar*   Pointer to a new psScalar.
+ */
+psScalar* psScalarAlloc(
+    psC64 value,                       ///< Data to be put into psScalar.
+    psElemType dataType                ///< Type of data to be held by psScalar.
+);
+
+/** Copy a scalar.
+ *
+ * Uses psLib memory allocation functions to copy a scalar.
+ *
+ * @return psScalar*    A copy of the input scalar
+ */
+psScalar* psScalarCopy(
+    psScalar *scalar                   ///< Scalar to copy.
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/mathtypes/psVector.c
===================================================================
--- /branches/rel3/psLib/src/mathtypes/psVector.c	(revision 2163)
+++ /branches/rel3/psLib/src/mathtypes/psVector.c	(revision 2163)
@@ -0,0 +1,412 @@
+
+/** @file  psVector.c
+*
+*  @brief Contains support for basic vector types
+*
+*  This file defines the basic type for a vector struct and functions useful
+*  in manupulating vectors.
+*
+*  @author Ross Harman, MHPCC
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.28 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-07 19:51:30 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include <string.h>                        // for memcpy
+#include <stdlib.h>
+#include <math.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psVector.h"
+#include "psLogMsg.h"
+#include "psCompare.h"
+
+#include "psCollectionsErrors.h"
+
+static void vectorFree(psVector* restrict psVec);
+
+
+static void vectorFree(psVector* restrict psVec)
+{
+    if (psVec == NULL) {
+        return;
+    }
+
+    psFree(psVec->data.V);
+}
+
+// FUNCTION IMPLEMENTATION - PUBLIC
+
+psVector* psVectorAlloc(unsigned int nalloc, psElemType elemType)
+{
+    psVector* psVec = NULL;
+    int elementSize = 0;
+
+    elementSize = PSELEMTYPE_SIZEOF(elemType);
+
+    // Create vector struct
+    psVec = (psVector* ) psAlloc(sizeof(psVector));
+    p_psMemSetDeallocator(psVec, (psFreeFcn) vectorFree);
+
+    psVec->type.dimen = PS_DIMEN_VECTOR;
+    psVec->type.type = elemType;
+    psVec->nalloc = nalloc;
+    psVec->n = nalloc;
+
+    // Create vector data array
+    psVec->data.V = psAlloc(nalloc * elementSize);
+
+    return psVec;
+}
+
+psVector* psVectorRealloc(psVector* restrict in, unsigned int nalloc)
+{
+    int elementSize = 0;
+    psElemType elemType;
+
+    if (in == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorRealloc",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psVector_REALLOC_NULL);
+        return NULL;
+    } else if (in->nalloc != nalloc) {     // No need to realloc to same size
+        elemType = in->type.type;
+        elementSize = PSELEMTYPE_SIZEOF(elemType);
+        if (nalloc < in->n) {
+            in->n = nalloc;
+        }
+        // Realloc after decrementation to avoid accessing freed array elements
+        in->data.V = psRealloc(in->data.V, nalloc * elementSize);
+        in->nalloc = nalloc;
+    }
+
+    return in;
+}
+
+psVector* psVectorRecycle(psVector* restrict in, unsigned int n, psElemType type)
+{
+    int byteSize;
+
+    if (in == NULL) {
+        return psVectorAlloc(n, type);
+    }
+
+    if (in->type.dimen !=  PS_DIMEN_VECTOR &&
+            in->type.dimen !=  PS_DIMEN_TRANSV) {
+        psFree(in);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorRecycle",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVector_NOT_A_VECTOR);
+        return NULL;
+    }
+
+    byteSize = n * PSELEMTYPE_SIZEOF(type);
+
+    // need to increase data buffer?
+    if (byteSize > in->nalloc*PSELEMTYPE_SIZEOF(in->type.type)) {
+        in->data.V = psRealloc(in->data.V, byteSize);
+        in->nalloc = n;
+    }
+
+    in->type.dimen = PS_DIMEN_VECTOR;
+    in->type.type = type;
+    in->n = n;
+    return in;
+}
+
+psVector* psVectorCopy(psVector* out, const psVector* in, psElemType type)
+{
+    if (in == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorSort",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psVector_SORT_NULL);
+        psFree(out);
+        return NULL;
+    }
+
+    int nElements = in->n;
+
+    out = psVectorRecycle(out, nElements, type);
+
+    #define PSVECTOR_COPY(INTYPE,OUTTYPE) { \
+        ps##INTYPE *inVec = in->data.INTYPE; \
+        ps##OUTTYPE *outVec = out->data.OUTTYPE; \
+        for (int col=0;col<nElements;col++) { \
+            *(outVec++) = *(inVec++); \
+        } \
+    }
+
+    #define PSVECTOR_COPY_CASE(OUTTYPE) \
+case PS_TYPE_##OUTTYPE: { \
+        switch (in->type.type) { \
+        case PS_TYPE_S8: \
+            PSVECTOR_COPY(S8,OUTTYPE); \
+            break; \
+        case PS_TYPE_S16: \
+            PSVECTOR_COPY(S16,OUTTYPE); \
+            break; \
+        case PS_TYPE_S32: \
+            PSVECTOR_COPY(S32,OUTTYPE); \
+            break; \
+        case PS_TYPE_S64: \
+            PSVECTOR_COPY(S64,OUTTYPE); \
+            break; \
+        case PS_TYPE_U8: \
+            PSVECTOR_COPY(U8,OUTTYPE); \
+            break; \
+        case PS_TYPE_U16: \
+            PSVECTOR_COPY(U16,OUTTYPE); \
+            break; \
+        case PS_TYPE_U32: \
+            PSVECTOR_COPY(U32,OUTTYPE); \
+            break; \
+        case PS_TYPE_U64: \
+            PSVECTOR_COPY(U64,OUTTYPE); \
+            break; \
+        case PS_TYPE_F32: \
+            PSVECTOR_COPY(F32,OUTTYPE); \
+            break; \
+        case PS_TYPE_F64: \
+            PSVECTOR_COPY(F64,OUTTYPE); \
+            break; \
+        case PS_TYPE_C32: \
+            PSVECTOR_COPY(C32,OUTTYPE); \
+            break; \
+        case PS_TYPE_C64: \
+            PSVECTOR_COPY(C64,OUTTYPE); \
+            break; \
+        default: { \
+                char* typeStr; \
+                PS_TYPE_NAME(typeStr,type); \
+                psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCopy", \
+                           PS_ERR_BAD_PARAMETER_TYPE, true, \
+                           PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE, \
+                           typeStr); \
+                psFree(out); \
+            } \
+        } \
+        break; \
+    }
+
+    switch (type) {
+        PSVECTOR_COPY_CASE(S8);
+        PSVECTOR_COPY_CASE(S16);
+        PSVECTOR_COPY_CASE(S32);
+        PSVECTOR_COPY_CASE(S64);
+        PSVECTOR_COPY_CASE(U8);
+        PSVECTOR_COPY_CASE(U16);
+        PSVECTOR_COPY_CASE(U32);
+        PSVECTOR_COPY_CASE(U64);
+        PSVECTOR_COPY_CASE(F32);
+        PSVECTOR_COPY_CASE(F64);
+        PSVECTOR_COPY_CASE(C32);
+        PSVECTOR_COPY_CASE(C64);
+    default: {
+            char* typeStr;
+            PS_TYPE_NAME(typeStr,type);
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psImageCopy",
+                       PS_ERR_BAD_PARAMETER_TYPE, true,
+                       PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE,
+                       typeStr);
+            psFree(out);
+
+            break;
+        }
+    }
+    return out;
+
+
+}
+
+psVector* psVectorSort(psVector* restrict outVector, const psVector* restrict inVector)
+{
+    int N = 0;
+    int elSize = 0;
+    void *inVec = NULL;
+    void *outVec = NULL;
+    psElemType inType = 0;
+
+    if (inVector == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorSort",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psVector_SORT_NULL);
+        psFree(outVector);
+        return NULL;
+    }
+
+    inType = inVector->type.type;
+    N = inVector->n;
+    inVec = inVector->data.V;
+    elSize = PSELEMTYPE_SIZEOF(inType);
+
+    if (outVector == NULL) {
+        outVector = psVectorAlloc(N, inType);
+    }
+
+    // check to see if output vector needs to be resized/retyped
+    if ( (N > outVector->nalloc) ||
+            (inType != outVector->type.type) ) {
+        // reshape the output vector to match the input vector's size/type.
+        outVector = psVectorRecycle(outVector,N,inType);
+    }
+    outVector->n = N;
+    outVec = outVector->data.V;
+
+    if (N == 0) {
+        // no need to sort anything, as there are no elements in input vector.
+        return outVector;
+    }
+
+    // Copy input vector values into output vector if not in-place sorting
+    if (inVector != outVector) {
+        memcpy(outVec, inVec, elSize * N);
+    }
+
+    // Sort output vector
+    switch (inType) {
+    case PS_TYPE_U8:
+        qsort(outVec, N, elSize, psCompareU8);
+        break;
+    case PS_TYPE_U16:
+        qsort(outVec, N, elSize, psCompareU16);
+        break;
+    case PS_TYPE_U32:
+        qsort(outVec, N, elSize, psCompareU32);
+        break;
+    case PS_TYPE_U64:
+        qsort(outVec, N, elSize, psCompareU64);
+        break;
+    case PS_TYPE_S8:
+        qsort(outVec, N, elSize, psCompareS8);
+        break;
+    case PS_TYPE_S16:
+        qsort(outVec, N, elSize, psCompareS16);
+        break;
+    case PS_TYPE_S32:
+        qsort(outVec, N, elSize, psCompareS32);
+        break;
+    case PS_TYPE_S64:
+        qsort(outVec, N, elSize, psCompareS64);
+        break;
+    case PS_TYPE_F32:
+        qsort(outVec, N, elSize, psCompareF32);
+        break;
+    case PS_TYPE_F64:
+        qsort(outVec, N, elSize, psCompareF64);
+        break;
+    default:
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorSort",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE,
+                   inType);
+    }
+
+    return outVector;
+}
+
+psVector* psVectorSortIndex(psVector* restrict outVector, const psVector* restrict inVector)
+{
+    int N = 0;
+    psVector* tmpVector = NULL;
+    psElemType inType = 0;
+    psU32* outVec;
+
+    if (inVector == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorSortIndex",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psVector_SORT_NULL);
+        psFree(outVector);
+        return NULL;
+    }
+
+    N = inVector->n;
+
+    if (outVector == NULL) {
+        outVector = psVectorAlloc(N, PS_TYPE_U32);
+    }
+
+    // check to see if output vector needs to be resized/retyped
+    if ( (N > outVector->nalloc) ||
+            (outVector->type.type != PS_TYPE_U32) ) {
+        // reshape the output vector to match the input vector's size/type.
+        outVector = psVectorRecycle(outVector,N,PS_TYPE_U32);
+    }
+    outVector->n = N;
+    outVec = outVector->data.U32;
+
+    if (N == 0) {
+        // no need to sort anything, as there are no elements in input vector.
+        return outVector;
+    }
+
+    tmpVector = psVectorSort(tmpVector, inVector);
+
+    #define SORT_INDICES(TYPE,absfcn,maxError) {                              \
+        ps##TYPE* inVec = inVector->data.TYPE;                                \
+        ps##TYPE* tmpVec = tmpVector->data.TYPE;                              \
+        ps##TYPE  diff;                                                       \
+        for(int i=0; i<N; i++) {                                              \
+            for(int j=0; j<N; j++) {                                          \
+                diff = absfcn(tmpVec[i] - inVec[j]);                          \
+                if(diff < maxError) {                                         \
+                    outVec[i] = j;                                            \
+                    break;                                                    \
+                }                                                             \
+            }                                                                 \
+        }                                                                     \
+    }
+
+    // Sort output vector
+    switch (inType) {
+    case PS_TYPE_U8:
+        SORT_INDICES(U8,/* no absfcn needed */,1);
+        break;
+    case PS_TYPE_U16:
+        SORT_INDICES(U16,/* no absfcn needed */,1);
+        break;
+    case PS_TYPE_U32:
+        SORT_INDICES(U32,/* no absfcn needed */,1);
+        break;
+    case PS_TYPE_U64:
+        SORT_INDICES(U64,/* no absfcn needed */,1);
+        break;
+    case PS_TYPE_S8:
+        SORT_INDICES(S8,/* no absfcn needed */,1);
+        break;
+    case PS_TYPE_S16:
+        SORT_INDICES(S16,/* no absfcn needed */,1);
+        break;
+    case PS_TYPE_S32:
+        SORT_INDICES(S32,/* no absfcn needed */,1);
+        break;
+    case PS_TYPE_S64:
+        SORT_INDICES(S64,/* no absfcn needed */,1);
+        break;
+    case PS_TYPE_F32:
+        SORT_INDICES(F32,fabsf,FLT_EPSILON);
+        break;
+    case PS_TYPE_F64:
+        SORT_INDICES(F64,fabs,DBL_EPSILON);
+        break;
+    case PS_TYPE_C32:
+        SORT_INDICES(F64,cabsf,FLT_EPSILON);
+        break;
+    case PS_TYPE_C64:
+        SORT_INDICES(F64,cabs,DBL_EPSILON);
+        break;
+    default:
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psVectorSortIndex",
+                   PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_psVector_UNSUPPORTED_TYPE,
+                   inType);
+    }
+
+    // Free temp memory
+    psFree(tmpVector);
+
+    return outVector;
+}
Index: /branches/rel3/psLib/src/mathtypes/psVector.h
===================================================================
--- /branches/rel3/psLib/src/mathtypes/psVector.h	(revision 2163)
+++ /branches/rel3/psLib/src/mathtypes/psVector.h	(revision 2163)
@@ -0,0 +1,147 @@
+/** @file  psVector.h
+ *
+ *  @brief Contains basic vector definitions and operations
+ *
+ *  This file defines the basic type for a vector struct and functions useful
+ *  in manupulating vectors.
+ *
+ *  @ingroup Vector
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.24 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-06 21:30:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_VECTOR_H
+#define PS_VECTOR_H
+
+#include "psType.h"
+
+/// @addtogroup Vector
+/// @{
+
+/** An vector to support primitive types.
+ *
+ * Struct for maintaining an vector of frequently used primitive types.
+ *
+ */
+typedef struct
+{
+    psType type;                ///< Type of data.
+    unsigned int nalloc;        ///< Total number of elements available.
+    unsigned int n;             ///< Number of elements in use.
+
+    union {
+        psU8* U8;               ///< Unsigned 8-bit integer data.
+        psU16* U16;             ///< Unsigned 16-bit integer data.
+        psU32* U32;             ///< Unsigned 32-bit integer data.
+        psU64* U64;             ///< Unsigned 64-bit integer data.
+        psS8* S8;               ///< Signed 8-bit integer data.
+        psS16* S16;             ///< Signed 16-bit integer data.
+        psS32* S32;             ///< Signed 32-bit integer data.
+        psS64* S64;             ///< Signed 64-bit integer data.
+        psF32* F32;             ///< Single-precision float data.
+        psF64* F64;             ///< Double-precision float data.
+        psC32* C32;             ///< Single-precision complex data.
+        psC64* C64;             ///< Double-precision complex data.
+        psPTR V;                ///< Pointer to data.
+    } data;                     ///< Union for data types.
+}
+psVector;
+
+/*****************************************************************************/
+
+/* FUNCTION PROTOTYPES                                                       */
+
+/*****************************************************************************/
+
+
+/** Allocate a vector.
+ *
+ *  Uses psLib memory allocation functions to create a vector collection of 
+ *  data as defined by the psType type.
+ *
+ * @return psVector*    Pointer to psVector.
+ */
+psVector* psVectorAlloc(
+    unsigned int nalloc,               ///< Total number of elements to make available.
+    psElemType dataType                ///< Type of data to be held by vector.
+);
+
+/** Reallocate a vector.
+ *
+ *  Uses psLib memory allocation functions to reallocate a vector collection 
+ *  of data. The vector is reallocated according to the psType type member 
+ *  contained within the vector.
+ *
+ *  @return psVector*      Pointer to psVector.
+ *
+ */
+psVector* psVectorRealloc(
+    psVector* restrict psVec,          ///< Vector to reallocate.
+    unsigned int nalloc                ///< Total number of elements to make available.
+);
+
+/** Recycle a vector.
+ *
+ *  Uses psLib memory allocation functions to reallocate a vector collection 
+ *  of data. The vector is reallocated according to the psElemType type 
+ *  parameter.
+ *
+ * @return psVector*       Pointer to psVector.
+ *
+ */
+psVector* psVectorRecycle(
+    psVector* restrict psVec,
+    ///< Vector to recycle.  If NULL, a new vector is created.  No effort
+    ///< taken to preserve the values.
+
+    unsigned int nalloc,               ///< Total number of elements to make available.
+    psElemType type                    ///< the datatype of the returned vector
+);
+
+/** Copy a vector, converting types.
+ *
+ *  Performs a deep copy of the elements of one psVector to a new psVector, 
+ *  converting numeric types to a specified type.
+ *
+ * @return psVector*       Pointer to resulting psVector.
+ *
+ */
+psVector* psVectorCopy(
+    psVector* out,                     ///< if non-NULL, a psVector to recycle
+    const psVector* in,                ///< the vector to copy.
+    psElemType type                    ///< the data type of the resulting psVector
+);
+
+/** Sort an array of floats.
+ *
+ *  Sorts an array of floats in ascending order.  This function is valid for
+ *  all non-complex data types.
+ *
+ *  @return  psVector*     Pointer to sorted psVector.
+ */
+psVector* psVectorSort(
+    psVector* restrict outVector,      ///< the output vector to recycle, or NULL if new vector desired.
+    const psVector* restrict inVector  ///< the vector to sort.
+);
+
+/** Creates an array of indices based on sort ordered of array.
+ *
+ *  Sorts a vector and creates an integer array holding indices of 
+ *  sorted float values based on pre-sort index positions.  
+ *
+ *  @return  psVector*     vector of the indices of sort.
+ */
+psVector* psVectorSortIndex(
+    psVector* restrict outVector,      ///< vector to recycle
+    const psVector* restrict inVector  ///< vector to sort
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/parseErrorCodes.pl
===================================================================
--- /branches/rel3/psLib/src/parseErrorCodes.pl	(revision 2163)
+++ /branches/rel3/psLib/src/parseErrorCodes.pl	(revision 2163)
@@ -0,0 +1,97 @@
+#!/usr/bin/perl
+
+# Provides functions for handling long command line options
+use Getopt::Long;
+
+my @ErrorCodes        = ();
+my @ErrorDescriptions = ();
+
+my $data = "psErrorCodes.dat";
+
+# Assign variables based on the presence of command line options to the script
+GetOptions(
+    "data=s"  => \$data,
+    "verbose" => \$verbose,
+    "help"    => \$help
+);
+
+if ($help) {
+    print "Usage: parseErrorCodes ", "[--data=$data] ", "[--help] ",
+      "[--verbose] filename [filename ...]\n\n";
+    exit(0);
+}
+
+print "Using data file '$data'\n" if $verbose;
+unless ( open( DATAFILE, "<", $data ) ) {
+    die "Can not open data file $data.";
+}
+
+print "Datafile:\n" if $verbose;
+while (<DATAFILE>) {
+    chop;
+    if (/^\s*\#/) {
+        print "C $_\n" if $verbose;
+    }
+    else {
+        if (/^\s*(\w+)\s+([\%\w].*)/) {
+            my $ErrorCode        = $1;
+            my $ErrorDescription = $2;
+            print "  $ErrorCode: '$ErrorDescription'\n" if $verbose;
+            push( @ErrorCodes,        $ErrorCode );
+            push( @ErrorDescriptions, $ErrorDescription );
+        } else {
+            print "I $_\n" if $verbose;
+        }
+    }
+}
+close(DATAFILE);
+
+my $found = $#ErrorCodes + 1;
+print "\nFound $found error codes.\n" if $verbose;
+
+foreach (@ARGV) {
+    my $filename = $_;
+    my @result   = ();
+
+    die "Failed to open input file"
+      if !open( INFILE, "<", $filename );
+
+    print "\nOutput File:\n" if $verbose;
+    while (<INFILE>) {
+        chop;
+        push( @result, $_ );
+        if (/^\s*\/\/~Start(.*)$/) {
+            $line = $1;
+            for ( $n = 0 ; $n < $found ; $n++ ) {
+                $_ = $line;
+                s/\$1/$ErrorCodes[$n]/g;
+                s/\$2/$ErrorDescriptions[$n]/g;
+                s/\$n/$n/g;
+                push( @result, $_ );
+                print "$_\n" if $verbose;
+            }
+
+            $break = 0;
+            while ( ( $break == 0 ) && ( $_ = <INFILE> ) ) {
+                if (/^\s*\/\/~End/) {
+                    $break = 1;
+                }
+            }
+            chop;
+            push( @result, $_ );
+        }
+    }
+
+    close(INFILE);
+
+    die "Failed to overwrite input file"
+      if !open( OUTFILE, ">", $filename );
+
+    foreach (@result) {
+        print OUTFILE "$_\n";
+        print "$_\n" if $verbose;
+    }
+
+    close(OUTFILE);
+
+}
Index: /branches/rel3/psLib/src/psErrorCodes.dat
===================================================================
--- /branches/rel3/psLib/src/psErrorCodes.dat	(revision 2163)
+++ /branches/rel3/psLib/src/psErrorCodes.dat	(revision 2163)
@@ -0,0 +1,18 @@
+#
+#  This file is used to generate psErrorCode.h content
+#
+# Format:
+#    ERROR_CLASS_NAME    ERROR_CLASS_DESCRIPTION
+#
+# Note: the ERROR_CLASS_NAME will appear in the code with a "PS_ERR_" prefix
+#
+UNKNOWN                        unknown error
+IO                             I/O error
+LOCATION_INVALID               specified location is unknown
+MEMORY_CORRUPTION              memory corruption detected
+MEMORY_DEREF_USAGE             dereferenced memory still used
+BAD_PARAMETER_VALUE            parameter is out-of-range
+BAD_PARAMETER_TYPE             parameter is of unsupported type
+BAD_PARAMETER_NULL             parameter is null
+BAD_PARAMETER_SIZE             size of parameter's data is outside of acceptable range.
+UNEXPECTED_NULL                unexpected NULL found
Index: /branches/rel3/psLib/src/pslib.h
===================================================================
--- /branches/rel3/psLib/src/pslib.h	(revision 2163)
+++ /branches/rel3/psLib/src/pslib.h	(revision 2163)
@@ -0,0 +1,166 @@
+
+/** @file  pslib.h
+*
+*  @brief Contains the complete list of header files for pslib.
+*
+*  This header file includes all the necessary header files for a user to
+*  user all public functions within the pslib library.
+*
+*  @author Eric Van Alst, MHPCC
+*
+*  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-14 21:14:57 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#ifndef PS_LIB_H
+#define PS_LIB_H
+
+/******************************************************************************/
+
+/*  INCLUDE FILES                                                             */
+
+/******************************************************************************/
+
+// System Utilities
+
+/// @defgroup SysUtils System Utilities
+/// @{
+
+/** @defgroup MemoryManagement Memory Management Utilities
+ *
+ *  This is the generic memory management system put inbetween the user's high level code and the OS-level
+ *  memory allocation routines.  This system adds such features as callback routines for memory error events,
+ *  tracing capabilities, and reference counting.
+ *
+ *  @ingroup SysUtils
+ */
+
+#include "fitsio.h"
+
+#include "psMemory.h"
+
+/// @defgroup LogTrace Tracing and Logging
+/// @ingroup SysUtils
+#include "psLogMsg.h"
+#include "psTrace.h"
+
+/// @defgroup ErrorHandling Error Handling
+/// @ingroup SysUtils
+#include "psAbort.h"
+#include "psError.h"
+
+#include "psString.h"
+
+/// @}
+
+// Collections
+/// @defgroup DataContainer Data Containers
+/// @{
+
+#include "psType.h"
+
+/// @defgroup LinkedList Linked List
+/// @ingroup DataContainer
+#include "psList.h"
+
+/// @defgroup HashTable Hash Table
+/// @ingroup DataContainer
+#include "psHash.h"
+
+/// @defgroup Scalar Scalar
+/// @ingroup DataContainer
+#include "psScalar.h"
+
+/// @defgroup Vector Vector Container
+/// @ingroup DataContainer
+#include "psVector.h"
+
+/// @defgroup Array Array Container
+/// @ingroup DataContainer
+#include "psArray.h"
+
+/// @defgroup Image Image Container
+/// @ingroup DataContainer
+/// @{
+#include "psImage.h"
+#include "psImageExtraction.h"
+#include "psImageManip.h"
+#include "psImageConvolve.h"
+
+/// @defgroup ImageIO Image File I/O Functions
+/// @ingroup Image
+#include "psImageIO.h"
+
+/// @defgroup ImageStats Image Statistical Functions
+/// @ingroup Image
+#include "psImageStats.h"
+
+/// @}
+
+/// @defgroup BitSet Bit Set Container
+/// @ingroup DataContainer
+#include "psBitSet.h"
+
+/// @}
+
+// Data Manipulation
+/// @defgroup DataManip Data Manipulation
+/// @{
+
+/// @defgroup Compare Comparison Functions
+/// @ingroup DataManip
+#include "psCompare.h"
+
+/// @defgroup Stats Statistic Functions
+/// @ingroup DataManip
+#include "psStats.h"
+
+/// @defgroup Matrix Matrix Operations
+/// @ingroup DataManip
+#include "psMatrix.h"
+
+/// @defgroup MatrixVectorArithmetic Matrix Vector Arithmetic Operations
+/// @ingroup DataManip
+#include "psMatrixVectorArithmetic.h"
+
+/// @defgroup Transform Fourier Transform Operations
+/// @ingroup DataManip
+#include "psVectorFFT.h"
+#include "psImageFFT.h"
+
+#include "psFunctions.h"
+#include "psMinimize.h"
+
+/// @}
+
+// Astronomy
+/// @defgroup Astronomy Astronomy Functions
+/// @{
+
+/// @defgroup CoordinateTransform Coordinate Functions
+/// @ingroup Astronomy
+#include "psCoord.h"
+
+/// @defgroup Photometry Photometry
+/// @ingroup Astronomy
+#include "psPhotometry.h"
+
+/// @defgroup Time Time Functions
+/// @ingroup Astronomy
+#include "psTime.h"
+
+/// @defgroup Metadata Metadata Functions
+/// @ingroup Astronomy
+#include "psMetadata.h"
+#include "psMetadataIO.h"
+
+/// @defgroup AstroImage Astrometry Functions
+/// @ingroup Astronomy
+#include "psAstrometry.h"
+
+#include "psConstants.h"
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/sys/psAbort.c
===================================================================
--- /branches/rel3/psLib/src/sys/psAbort.c	(revision 2163)
+++ /branches/rel3/psLib/src/sys/psAbort.c	(revision 2163)
@@ -0,0 +1,38 @@
+
+/** @file  psAbort.c
+ *
+ *  @brief Contains the definition for abort function
+ *
+ *  The abort logging and handling shall be performed by psAbort function.
+ *  This will allow for consistent handling of other software units
+ *  needing to abort from program execution.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *   
+ *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-07 19:05:07 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include "psAbort.h"
+#include "psLogMsg.h"
+
+void psAbort(const char *name, const char *fmt, ...)
+{
+    va_list argPtr;             // variable list arguement pointer
+
+    // Get the variable list parameters to pass to logging function
+    va_start(argPtr, fmt);
+
+    // Call logging function with PS_LOG_ABORT level
+    psLogMsgV(name, PS_LOG_ABORT, fmt, argPtr);
+
+    // Clean up stack after variable arguement has been used
+    va_end(argPtr);
+
+    // Call system abort function to terminate program execution
+    abort();
+}
Index: /branches/rel3/psLib/src/sys/psAbort.h
===================================================================
--- /branches/rel3/psLib/src/sys/psAbort.h	(revision 2163)
+++ /branches/rel3/psLib/src/sys/psAbort.h	(revision 2163)
@@ -0,0 +1,47 @@
+
+/** @file  psAbort.h
+ *
+ *  @brief Contains the declarations for the abort function
+ *
+ *  The abort logging and handling shall be performed by psAbort function.
+ *  This will allow for consistent handling of other software units
+ *  needing to abort from program execution.
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-10 01:55:34 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ABORT_H
+#define PS_ABORT_H
+
+// Doxygen grouping tags
+
+/** @addtogroup ErrorHandling
+ *  @{
+ */
+
+/** Reports an abort message to logging facility
+ *
+ *  This function will invoke the psLogMsg function with a level of 
+ *  PS_LOG_ABORT and pass the parameters name and fmt to generate a proper
+ *  log message.  After logging, this function will call system abort 
+ *  function to abnormally terminate the program.
+ *
+ *  @return  void No return value
+ *
+ */
+void psAbort(
+    const char *name,                  ///< Source of abort such as file or function detected
+    const char *fmt,                   ///< A printf style formatting statement defining msg
+    ...
+);
+
+/* @} */// Doxygen - End of SystemGroup Functions
+
+#endif
Index: /branches/rel3/psLib/src/sys/psError.c
===================================================================
--- /branches/rel3/psLib/src/sys/psError.c	(revision 2163)
+++ /branches/rel3/psLib/src/sys/psError.c	(revision 2163)
@@ -0,0 +1,199 @@
+/** @file  psError.c
+ *
+ *  @brief Contains the definitions for the error reporting functions
+ *
+ *  Error reporting functions shall be used to create log entries in the
+ *  event errors are detected.  The messages shall give enough information
+ *  to allow the user to know where the error has occurred and the type
+ *  of error detected.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *   
+ *  @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-27 20:38:02 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdarg.h>
+#include <pthread.h>
+#include <string.h>
+
+#include "psLogMsg.h"
+#include "psError.h"
+#include "psMemory.h"
+
+#define MAX_ERROR_STACK_SIZE 64
+static psErr* errorStack[MAX_ERROR_STACK_SIZE];
+static unsigned int errorStackSize = 0;
+pthread_mutex_t lockErrorStack = PTHREAD_MUTEX_INITIALIZER;
+
+static void pushErrorStack(psErr* err);
+
+static void pushErrorStack(psErr* err)
+{
+
+    pthread_mutex_lock(&lockErrorStack);
+
+    if (errorStackSize < MAX_ERROR_STACK_SIZE) {
+        errorStack[errorStackSize] = psMemIncrRefCounter(err);
+        errorStackSize++;
+        p_psMemSetPersistent(err,true);
+        p_psMemSetPersistent(err->msg,true);
+        p_psMemSetPersistent(err->name,true);
+    }
+
+    pthread_mutex_unlock(&lockErrorStack);
+}
+
+static void errFree(psErr* err)
+{
+    if (err != NULL) {
+        psFree(err->msg);
+        psFree(err->name);
+    }
+}
+
+psErr* psErrAlloc(const char* name, psErrorCode code, const char* msg)
+{
+    psErr* err = psAlloc(sizeof(psErr));
+    err->msg = strcpy(psAlloc(strlen(msg) + 1), msg);
+    err->name = strcpy(psAlloc(strlen(name) + 1), name);
+    err->code = code;
+
+    p_psMemSetDeallocator(err,(psFreeFcn)errFree);
+
+    return err;
+}
+
+void psError(const char *name, const char *fmt, ...)
+{
+    va_list argPtr;             // variable list arguement pointer
+
+    // Get the variable list parameters to pass to logging function
+    va_start(argPtr, fmt);
+
+    // Call logging function with PS_LOG_ERROR level
+    psLogMsgV(name, PS_LOG_ERROR, fmt, argPtr);
+
+    // Clean up stack after variable argument has been used
+    va_end(argPtr);
+}
+
+void psErrorClear()
+{
+    pthread_mutex_lock(&lockErrorStack);
+    for (int lcv=0;lcv<errorStackSize;lcv++) {
+        p_psMemSetPersistent(errorStack[lcv]->msg,false);
+        p_psMemSetPersistent(errorStack[lcv]->name,false);
+        p_psMemSetPersistent(errorStack[lcv],false);
+        psFree(errorStack[lcv]);
+    }
+    errorStackSize = 0;
+    pthread_mutex_unlock(&lockErrorStack);
+}
+
+psErrorCode psErrorMsg(const char *name, psErrorCode code, bool new, const char* fmt, ...)
+{
+    char errMsg[1024];
+    psErr* err;
+    char* msgName;
+
+    // Check for null pointer and if found set to empty string;
+    if ( name == NULL ) {
+        msgName = "";
+    } else {
+        msgName = (char*)name;
+    }
+
+    va_list argPtr;             // variable list arguement pointer
+
+    if (new) {
+        psErrorClear();
+    }
+
+    // Get the variable list parameters to pass to logging function
+    va_start(argPtr, fmt);
+
+    vsnprintf(errMsg,1024,fmt,argPtr);
+    err = psErrAlloc(msgName,code,errMsg);
+    pushErrorStack(err);
+
+    // Call logging function with PS_LOG_ERROR level
+    psLogMsg(msgName, PS_LOG_ERROR, errMsg);
+
+    // Clean up stack after variable argument has been used
+    va_end(argPtr);
+
+    psFree(err);
+
+    return code;
+}
+
+psErr* psErrorGet(int which)
+{
+    psErr* result;
+
+    pthread_mutex_lock(&lockErrorStack);
+
+    // Check for negative reference and if found return PS_ERR_NONE
+    if (which < 0 ) {
+        result = psErrAlloc("", PS_ERR_NONE, "");
+    } else {
+
+        which = errorStackSize-1-which;     // the which input is from the end of errorStack
+        if (which < 0 || which >= errorStackSize) {
+            result = psErrAlloc("",PS_ERR_NONE,"");    // no error at the given location
+        } else {
+            result = psMemIncrRefCounter(errorStack[which]); // a new reference passed back
+        }
+    }
+
+    pthread_mutex_unlock(&lockErrorStack);
+
+    return result;
+}
+
+psErr* psErrorLast(void)
+{
+    return psErrorGet(0);
+}
+
+void psErrorStackPrint(FILE *fd, const char *fmt, ...)
+{
+    va_list argPtr;             // variable list arguement pointer
+
+    // Get the variable list parameters to pass to logging function
+    va_start(argPtr, fmt);
+
+    psErrorStackPrintV(fd,fmt,argPtr);
+
+    va_end(argPtr);
+}
+
+void psErrorStackPrintV(FILE *fd, const char *fmt, va_list va)
+{
+
+    pthread_mutex_lock(&lockErrorStack);
+
+    if (errorStackSize > 0) {
+        vfprintf(fd,fmt,va);
+
+        for (int lcv=0;lcv<errorStackSize;lcv++) {
+            if(errorStack[lcv]->code >= PS_ERR_BASE) {
+                fprintf(fd," -> %s: %s\n     %s\n",
+                        errorStack[lcv]->name,
+                        psErrorCodeString(errorStack[lcv]->code),
+                        errorStack[lcv]->msg);
+            } else {
+                fprintf(fd," -> %s: %s\n     %s\n",
+                        errorStack[lcv]->name,
+                        strerror(errorStack[lcv]->code),
+                        errorStack[lcv]->msg);
+            }
+        }
+    }
+
+    pthread_mutex_unlock(&lockErrorStack);
+}
+
Index: /branches/rel3/psLib/src/sys/psError.h
===================================================================
--- /branches/rel3/psLib/src/sys/psError.h	(revision 2163)
+++ /branches/rel3/psLib/src/sys/psError.h	(revision 2163)
@@ -0,0 +1,142 @@
+/** @file  psError.h
+ *
+ *  @brief Contains the declarations for the error reporting functions
+ *
+ *  Error reporting functions shall be used to create log entries in the
+ *  event errors are detected.  The messages shall give enough information
+ *  to allow the user to know where the error has occurred and the type
+ *  of error detected.
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-23 22:18:13 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ERROR_H
+#define PS_ERROR_H
+
+#include<stdio.h>
+#include<stdbool.h>
+#include<stdarg.h>
+
+#include "psErrorCodes.h"
+
+/** @addtogroup ErrorHandling
+ *  @{
+ */
+
+/** Error message object */
+typedef struct
+{
+    char* name;                        ///< category of code that caused the error
+    psErrorCode code;                  ///< class of error
+    char* msg;                         ///< the message associated with the error
+}
+psErr;
+
+/** Get a error from the error stack
+ *
+ *  Previous errors on the stack are returned by psErrorGet (a value of 0 
+ *  passed to psErrorGet is equivalent to a call to psErrorLast).
+ *
+ *  if no error is at the which position, a non-NULL psErr is returned with 
+ *  code PS_ERR_NONE.
+ *
+ *  @return    Error message object at 'which'
+ */
+psErr* psErrorGet(
+    int which                          ///< position in the error stack. 0 is last error on stack.
+);
+
+/** Get last error put on the error stack
+ *
+ *  The last error reported is available from psErrorLast; if no errors are 
+ *  current, a non-NULL psErr is returned with code PS_ERR_NONE.
+ *
+ *  @return psErr*     Reference to last error message on error stack
+ */
+psErr* psErrorLast(void);
+
+/** Clears the error stack.
+ *
+ *  The error stack may be completely cleared with psErrorClear.
+ *
+ */
+void psErrorClear(void);
+
+/** Prints error stack to specified open file descriptor
+ *
+ *  The entire error stack may be printed to an open file descriptor by 
+ *  calling psErrorStackPrint; if and only if there are current errors, the 
+ *  printf-style string fmt is first printed to the file descriptor fd. In 
+ *  this printout, error codes are replaced by their string equivalents.
+ *
+ */
+void psErrorStackPrint(
+    FILE* fd,                          ///< destination file descriptor
+    const char* fmt,                   ///< printf-style format of header line
+    ...                                ///< any parameters required in fmt
+);
+
+/** Prints error stack to specified open file descriptor
+ *
+ *  The entire error stack may be printed to an open file descriptor by 
+ *  calling psErrorStackPrintV; if and only if there are current errors, the 
+ *  vprintf-style string fmt is first printed to the file descriptor fd. In 
+ *  this printout, error codes are replaced by their string equivalents.
+ *
+ */
+void psErrorStackPrintV(
+    FILE* fd,                          ///< destination file descriptor
+    const char* fmt,                   ///< printf-style format of header line
+    va_list va                         ///< any parameters required in fmt
+);
+
+/** Reports an error message to the logging facility
+ *
+ *  This function will invoke the psLogMsg function with a level of
+ *  PS_LOG_ERROR and pass the parameters name and fmt to generate a proper
+ *  log message.
+ *
+ */
+void psError(
+    const char *name,                  ///< Source of error such as file or function detected
+    const char *fmt,                   ///< A printf style formatting statement defining msg
+    ...
+);
+
+/** Reports an error message to the logging facility
+ *
+ *  This function will invoke the psLogMsg function with a level of
+ *  PS_LOG_ERROR and pass the parameters name and fmt to generate a proper
+ *  log message.
+ *
+ */
+psErrorCode psErrorMsg(
+    const char *name,                  ///< Name of error in the form aaa.bbb.ccc
+    psErrorCode code,                  ///< Error class code
+    bool new,                          ///< true if error originates at this location
+    const char* fmt,                   ///< printf style formatting statement defining error message
+    ...
+);
+
+/** Create a new psErr struct
+ *
+ *  Creates a new psErr struct, making a copy of the parameters.
+ *
+ *  @return psErr*     new psErr object
+ */
+psErr* psErrAlloc(
+    const char* name,                  ///< Name of error in the form aaa.bbb.ccc
+    psErrorCode code,                  ///< Error class code
+    const char* msg                    ///< Error message
+);
+
+/* @} */// End of SysUtils Functions
+
+#endif
Index: /branches/rel3/psLib/src/sys/psErrorCodes.c
===================================================================
--- /branches/rel3/psLib/src/sys/psErrorCodes.c	(revision 2163)
+++ /branches/rel3/psLib/src/sys/psErrorCodes.c	(revision 2163)
@@ -0,0 +1,182 @@
+/** @file  psErrorCodes.c
+ *
+ *  @brief Contains the error codes for the error classes
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 21:14:58 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <string.h>
+
+#include "psError.h"
+#include "psErrorCodes.h"
+#include "psList.h"
+#include "psMemory.h"
+
+#include "psSysUtilsErrors.h"
+
+/* N.B., lines between '//~Start' and '//~End' are automatic generated from
+ * the template following the '//~Start'.  The template is used to generate
+ * the other lines by, for each error class in psErrorCodes.dat, the following
+ * substitutions are made:
+ *     $1  The error code name (first word in the psErrorCodes.dat lines)
+ *     $2  The error description (rest of the line in psErrorCodes.dat)
+ *     $n  The order of the source line in psErrorCodes.dat (comments excluded)
+ * 
+ * DO NOT EDIT THE LINES BETWEEN //~Start and //~End!  ANY CHANGES WILL BE OVERWRITTEN.
+ */
+
+static psErrorDescription staticErrorCodes[] = {
+            {PS_ERR_NONE,"not an error"},
+            {PS_ERR_BASE,"base error"},
+            //~Start    {PS_ERR_$1,"$2"},
+            {PS_ERR_UNKNOWN,"unknown error"},
+            {PS_ERR_IO,"I/O error"},
+            {PS_ERR_LOCATION_INVALID,"specified location is unknown"},
+            {PS_ERR_MEMORY_CORRUPTION,"memory corruption detected"},
+            {PS_ERR_MEMORY_DEREF_USAGE,"dereferenced memory still used"},
+            {PS_ERR_BAD_PARAMETER_VALUE,"parameter is out-of-range"},
+            {PS_ERR_BAD_PARAMETER_TYPE,"parameter is of unsupported type"},
+            {PS_ERR_BAD_PARAMETER_NULL,"parameter is null"},
+            {PS_ERR_BAD_PARAMETER_SIZE,"size of parameter's data is outside of acceptable range."},
+            {PS_ERR_UNEXPECTED_NULL,"unexpected NULL foun"},
+            //~End
+            {PS_ERR_N_ERR_CLASSES,"error classes end marker"}
+        };
+
+static psList* dynamicErrorCodes = NULL;
+static const psErrorDescription* getErrorDescription(psErrorCode code);
+
+
+static const psErrorDescription* getErrorDescription(psErrorCode code)
+{
+    // first, search the static error codes
+
+    int n = 0;
+    while(staticErrorCodes[n].code != PS_ERR_N_ERR_CLASSES &&
+            staticErrorCodes[n].code != code) {
+        n++;
+    }
+
+    if (staticErrorCodes[n].code == code) {
+        return &staticErrorCodes[n];
+    } else {
+        psErrorDescription* desc;
+        // make sure there is a list to search
+        if (dynamicErrorCodes == NULL) {
+            return NULL;
+        }
+
+        // search dynamic list of error descriptions before giving up.
+        desc = (psErrorDescription*)psListGet(dynamicErrorCodes,PS_LIST_HEAD);
+        while (desc != NULL) {
+            if (desc->code == code) {
+                return desc;
+            }
+            desc = (psErrorDescription*)psListGetNext(dynamicErrorCodes);
+        }
+    }
+    return NULL;
+}
+
+static void freeErrorDescription(psErrorDescription* err)
+{
+    psFree((void*)err->description);
+}
+
+psErrorDescription* psErrorDescriptionAlloc(psErrorCode code,
+        const char *description)
+{
+    psErrorDescription* err = psAlloc(sizeof(psErrorDescription));
+    err->code = code;
+    if (description == NULL) {
+        err->description = NULL;
+    } else {
+        err->description = psAlloc(sizeof(char)*strlen(description)+1);
+        strcpy((char*)err->description,description);
+    }
+
+    p_psMemSetDeallocator(err,(psFreeFcn)freeErrorDescription);
+    return err;
+}
+
+
+const char *psErrorCodeString(psErrorCode code)
+{
+    // Check input argument is non-negative
+    if ( code < 0 ) {
+        return NULL;
+    }
+
+    const psErrorDescription* desc = getErrorDescription(code);
+
+    if (desc == NULL) {
+        return NULL;
+    }
+
+    return desc->description;
+}
+
+void psErrorRegister(const psErrorDescription* errors,
+                     int nerror)
+{
+    if (nerror < 1) {
+        return;
+    }
+
+    if (errors == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psErrorRegister",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psErrorCode_NULL_ERRORDESCRIPTION);
+        return;
+    }
+
+    if (dynamicErrorCodes == NULL) {
+        dynamicErrorCodes = psListAlloc(NULL);
+        p_psMemSetPersistent(dynamicErrorCodes,true);
+    }
+
+    for (int i=0;i<nerror;i++) {
+        psErrorDescription* err = psErrorDescriptionAlloc(
+                                      errors[i].code, errors[i].description);
+        p_psMemSetPersistent(err,true);
+        p_psMemSetPersistent((void*)err->description,true);
+        if (! psListAdd(dynamicErrorCodes,
+                        PS_LIST_HEAD,
+                        err) ) {
+
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psErrorRegister",
+                       PS_ERR_UNKNOWN, false,
+                       PS_ERRORTEXT_psErrorCode_ERRORCODE_REGISTER_FAILED,
+                       i);
+        }
+        p_psMemSetPersistent(dynamicErrorCodes->head,true);
+        psFree(err);
+    }
+}
+
+bool p_psErrorUnregister(psErrorCode code)
+{
+    // Check input argument is non-negative
+    if ( code < 0 ) {
+        return false;
+    }
+
+    const psErrorDescription* desc = getErrorDescription(code);
+
+    if (desc == NULL) {
+        return false;
+    }
+
+    if (dynamicErrorCodes == NULL) {
+        return false;
+    }
+
+    return psListRemove(dynamicErrorCodes,PS_LIST_UNKNOWN,(void*)desc);
+}
Index: /branches/rel3/psLib/src/sys/psErrorCodes.h
===================================================================
--- /branches/rel3/psLib/src/sys/psErrorCodes.h	(revision 2163)
+++ /branches/rel3/psLib/src/sys/psErrorCodes.h	(revision 2163)
@@ -0,0 +1,108 @@
+/** @file  psErrorCodes.h
+ *
+ *  @brief Contains the error codes for the error classes
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 21:14:58 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ERROR_CODES_H
+#define PS_ERROR_CODES_H
+
+/* N.B., lines between '//~Start' and '//~End' are automatic generated from
+ * the template following the '//~Start'.  The template is used to generate
+ * the other lines by, for each error class in psErrorCodes.dat, the following
+ * substitutions are made:
+ *     $1  The error code name (first word in the psErrorCodes.dat lines)
+ *     $2  The error description (rest of the line in psErrorCodes.dat)
+ *     $n  The order of the source line in psErrorCodes.dat (comments excluded)
+ * 
+ * DO NOT EDIT THE LINES BETWEEN //~Start and //~End!  ANY CHANGES WILL BE OVERWRITTEN.
+ */
+
+/** @addtogroup ErrorHandling
+ *  @{
+ */
+
+/** enumeration of the static error code classes
+ */
+typedef enum {
+    PS_ERR_NONE = 0,                   ///< not an error
+    PS_ERR_BASE = 256,
+    /**< base error.  Any psErrorCode less than this should be taken to be
+     *   valid values of errno
+     */
+
+    //~Start     PS_ERR_$1,   ///< $2
+    PS_ERR_UNKNOWN,   ///< unknown error
+    PS_ERR_IO,   ///< I/O error
+    PS_ERR_LOCATION_INVALID,   ///< specified location is unknown
+    PS_ERR_MEMORY_CORRUPTION,   ///< memory corruption detected
+    PS_ERR_MEMORY_DEREF_USAGE,   ///< dereferenced memory still used
+    PS_ERR_BAD_PARAMETER_VALUE,   ///< parameter is out-of-range
+    PS_ERR_BAD_PARAMETER_TYPE,   ///< parameter is of unsupported type
+    PS_ERR_BAD_PARAMETER_NULL,   ///< parameter is null
+    PS_ERR_BAD_PARAMETER_SIZE,   ///< size of parameter's data is outside of acceptable range.
+    PS_ERR_UNEXPECTED_NULL,   ///< unexpected NULL foun
+    //~End
+    PS_ERR_N_ERR_CLASSES               ///< end marker - should not be used as a true error
+} psErrorCode;
+
+/** An error code with description
+ */
+typedef struct
+{
+    psErrorCode code;                  ///< An error code
+    const char *description;           ///< the associated description
+}
+psErrorDescription;
+
+/** Allocates a new psErrorDescription
+ *
+ *  @return psErrorDescription*        new psErrorDescription struct.
+ */
+psErrorDescription* psErrorDescriptionAlloc(
+    psErrorCode code,                  ///< An error code
+    const char *description            ///< the associated description
+);
+
+/** Retrieves the description of an error code.
+ *
+ *  The routine psErrorCodeString returns the string associated with an error 
+ *  code.
+ *
+ *  @return const char*     the description associated with the given code.
+ */
+const char *psErrorCodeString(
+    psErrorCode code                   ///< the associated error code
+);
+
+/** Register an error code
+ *
+ *  Any project needed to use psLib must define the necessary error codes and
+ *  associated message strings.  This function registers an array of error 
+ *  codes with the error handling subsystem.
+ *
+ */
+void psErrorRegister(
+    const psErrorDescription* errors,  ///< Array of error codes to register
+    int nerror                         ///< number of errors in input array
+);
+
+/** Clears error codes registered via psErrorRegister.
+ *
+ *  @return bool    TRUE if given errorcode was removed, otherwise FALSE.
+ */
+bool p_psErrorUnregister(
+    psErrorCode code                   ///< the error code to find and remove
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/sys/psLogMsg.c
===================================================================
--- /branches/rel3/psLib/src/sys/psLogMsg.c	(revision 2163)
+++ /branches/rel3/psLib/src/sys/psLogMsg.c	(revision 2163)
@@ -0,0 +1,392 @@
+/** @file  psLogMsg.c
+ *  @brief Procedures for logging messages.
+ *  \ingroup LogTrace
+ *
+ *  This file will hold the prototypes for defining procedure which set
+ *  message log levels, messahe log formats, message log destinations, and
+ *  for generating the messages themselves.
+ *  @ingroup LogTrace
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.33 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-14 20:01:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/*****************************************************************************
+NOTES: currently, the prototype code has the following global variables:
+    static int p_psGlobalLogDest;
+    static int p_psGlobalLogLevel;
+    static int p_psLogTime;
+    static int p_psLogHost;
+    static int p_psLogLevel;
+    static int p_psLogName;
+    static int p_psLogMsg;
+ *****************************************************************************/
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include "psLogMsg.h"
+#include "psError.h"
+#include "psTrace.h"
+
+#include "psSysUtilsErrors.h"
+
+#define MIN_LOG_LEVEL 0
+#define MAX_LOG_LEVEL 9
+
+#define MAX_LOG_LINE_LENGTH 128
+
+
+static FILE *logDest = (FILE *) 1;      // flag to initialize to stderr before using.
+static int globalLogLevel = PS_LOG_INFO;        // log all messages at this or above
+static bool logTime = true;     // Flag to include time info
+static bool logHost = true;     // Flag to include host info
+static bool logLevel = true;    // Flag to include level info
+static bool logName = true;     // Flag to include name info
+static bool logMsg = true;      // Flag to include message info
+
+/*****************************************************************************
+psLogSetLevel(): Set the current log level and return old level.
+Input:
+ level (int): the new log level.
+Output:
+ none
+Return:
+ The old log level.
+ *****************************************************************************/
+int psLogSetLevel(int level)
+{
+    // Save old global log level for changing it.
+    int oldLevel = globalLogLevel;
+
+    if ((level < MIN_LOG_LEVEL) || (level > MAX_LOG_LEVEL)) {
+        psLogMsg("logmsg", PS_LOG_WARN, "Attempt to set invalid logMsg level: %d", level);
+        level = (level < MIN_LOG_LEVEL) ? MIN_LOG_LEVEL : MAX_LOG_LEVEL;
+    }
+    // Set new global log level
+    globalLogLevel = level;
+
+    // Return old global log level
+    return oldLevel;
+}
+
+/*****************************************************************************
+psLogSetDestination(): sets the destination where log messages will be
+sent to.
+ 
+Input:
+ dest (int): the new log destination
+Output:
+ None.
+Return:
+ An integer specifying the old log destination.
+ *****************************************************************************/
+bool psLogSetDestination(const char *dest)
+{
+    char protocol[5];
+    char location[257];
+
+    // if logDest has not been initialized, do so before using it
+    if (logDest == (FILE *) 1) {
+        logDest = stderr;
+    }
+
+    if (dest == NULL || strcmp(dest, "none") == 0) {
+        if (logDest != NULL && logDest != stderr && logDest != stdout) {
+            fclose(logDest);
+        }
+        logDest = NULL;
+        return true;
+    }
+
+    if (sscanf(dest, "%4s:%256s", protocol, location) < 2) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psLogSetDestination", true, PS_ERR_LOCATION_INVALID,
+                   PS_ERRORTEXT_psLogMsg_DESTINATION_MALFORMED,
+                   dest);
+        return false;
+    }
+
+    if (strcmp(protocol, "dest") == 0) {
+        if (strcmp(location, "stderr") == 0) {
+            if (logDest != NULL && logDest != stderr && logDest != stdout) {
+                fclose(logDest);
+            }
+            logDest = stderr;
+            return true;
+        }
+        if (strcmp(location, "stdout") == 0) {
+            if (logDest != NULL && logDest != stderr && logDest != stdout) {
+                fclose(logDest);
+            }
+            logDest = stdout;
+            return true;
+        }
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psLogSetDestination", true, PS_ERR_LOCATION_INVALID,
+                   PS_ERRORTEXT_psLogMsg_DEST_LOCATION_INVALID,
+                   location);
+        return 1;
+    } else if (strcmp(protocol, "file") == 0) {
+        FILE *file = fopen(location, "w");
+
+        if (file == NULL) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psLogSetDestination", true, PS_ERR_IO,
+                       PS_ERRORTEXT_psLogMsg_OPEN_FILE_FAILED,
+                       location);
+            return false;
+        }
+        if (logDest != NULL && logDest != stderr && logDest != stdout) {
+            fclose(logDest);
+        }
+        logDest = file;
+        return true;
+    }
+
+    psErrorMsg(PS_ERRORNAME_DOMAIN "psLogSetDestination", true, PS_ERR_LOCATION_INVALID,
+               PS_ERRORTEXT_psLogMsg_UNSUPPORTED_PROTOCOL,
+               protocol);
+    return false;
+}
+
+/*****************************************************************************
+psLogSetFormat(): Set the format of psLogMsg output.  More precisely,
+    provide a string consisting of the letters {H (host), L (level), M
+    (message), N (name), T (time)}.  The default is "HLMNT".  This string
+    determines whether or not they associated type of information will be
+    included in message logs.  It does not determine the order in which that
+    information will appear (that order is fixed).
+ 
+Input:
+    fmt: a string specifying the format.
+Output:
+    none.
+Return:
+    NULL.
+ *****************************************************************************/
+void psLogSetFormat(const char *fmt)
+{
+    // assume nothing desired unless specified
+    logHost = false;
+    logLevel = false;
+    logMsg = false;
+    logName = false;
+    logTime = false;
+
+    // if fmt is NULL, no logging is desired.
+    if (fmt == NULL) {
+        return;
+    }
+
+    if (strlen(fmt) == 0) {
+        fmt = "THLNM";
+    }
+    // Step through each character in the format string.  For each letter
+    // in that string, set/unset the appropriate logging.
+
+    for (const char *ptr = fmt; *ptr != '\0'; ptr++) {
+        switch (*ptr) {
+        case 'H':
+        case 'h':
+            logHost = true;
+            break;
+        case 'L':
+        case 'l':
+            logLevel = true;
+            break;
+        case 'M':
+        case 'm':
+            logMsg = true;
+            break;
+        case 'N':
+        case 'n':
+            logName = true;
+            break;
+        case 'T':
+        case 't':
+            logTime = true;
+            break;
+        default:
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psLogSetFormat", true, PS_ERR_BAD_PARAMETER_VALUE,
+                       PS_ERRORTEXT_psLogMsg_UNKNOWN_KEY, *ptr);
+            break;
+        }
+    }
+
+    if (!logMsg) {
+        psTrace("utils.logMsg", 1, "You must at least log error messages (You chose \"%s\")", fmt);
+    }
+}
+
+#if !defined(HOST_NAME_MAX)                // should be in limits.h
+#define HOST_NAME_MAX 256
+#endif
+
+/*****************************************************************************
+    psVLogMsg(): This routine sends the message, which is a printf style
+ string specified in the "..." argument, to the current message log
+ destination with the severity specified by the "level" argument.
+    Input:
+ name
+ level
+ fmt
+ ap
+    Output:
+ none
+    Return:
+ NULL.
+ *****************************************************************************/
+void psLogMsgV(const char *name, int level, const char *fmt, va_list ap)
+{
+    static int first = 1;       // Flag for calling gethostname()
+    static char hostname[HOST_NAME_MAX + 1];
+
+    // Buffer for hostname.
+    char clevel = 0;            // letter-name for level
+    char head[MAX_LOG_LINE_LENGTH + 2]; // the added two are for the ending | and \0
+    char *head_ptr = head;      // where we've got to in head
+    int maxLength = MAX_LOG_LINE_LENGTH;
+    time_t clock = time(NULL);  // The current time.
+    struct tm *utc = gmtime(&clock);    // The current gm time.
+
+    // if logDest has not been initialized, do so before using it
+    if (logDest == (FILE *) 1) {
+        logDest = stderr;
+    }
+    // If logging is off, or if the level is too high, return immediately.
+    if ((level > globalLogLevel) || (logDest == NULL)) {
+        return;
+    }
+    // If I have not been here yet, determine my hostname and save it.
+    if (first) {
+        first = 0;
+        gethostname(hostname, HOST_NAME_MAX);
+    }
+
+    switch (level) {
+    case PS_LOG_ABORT:
+        clevel = 'A';
+        break;
+
+    case PS_LOG_ERROR:
+        clevel = 'E';
+        break;
+
+    case PS_LOG_WARN:
+        clevel = 'W';
+        break;
+
+    case PS_LOG_INFO:
+        clevel = 'I';
+        break;
+
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+        clevel = level + '0';
+        break;
+
+    default:
+        psTrace("utils.logMsg", 2, "Invalid logMsg level: %d (%s)\n", level, fmt);
+        level = (level < 0) ? 0 : 9;
+        clevel = level + '0';
+        break;
+    }
+
+    // Create the various log fields...
+    if (logTime) {
+        maxLength -= snprintf(head_ptr, maxLength, "%4d:%02d:%02d %02d:%02d:%02dZ",
+                              utc->tm_year + 1900, utc->tm_mon + 1, utc->tm_mday,
+                              utc->tm_hour, utc->tm_min, utc->tm_sec) - 1;
+        head_ptr += strlen(head_ptr);
+    }
+    // Hostname should be 20 characters.
+    if (logHost) {
+        if (head_ptr > head) {
+            *head_ptr++ = '|';
+        }
+        maxLength -= snprintf(head_ptr, maxLength, "%-20s", hostname);
+        head_ptr += strlen(head_ptr);
+    }
+    if (logLevel) {
+        if (head_ptr > head) {
+            *head_ptr++ = '|';
+        }
+        maxLength -= snprintf(head_ptr, maxLength, "%c", clevel);
+        head_ptr += strlen(head_ptr);
+    }
+    if (logName) {
+        if (head_ptr > head) {
+            *head_ptr++ = '|';
+        }
+        maxLength -= snprintf(head_ptr, maxLength, "%s", name);
+
+        head_ptr += strlen(head_ptr);
+    }
+
+    if (head_ptr > head) {
+        *head_ptr++ = '\n';
+    } else if (!logMsg) {                  // no output desired
+        return;
+    }
+    *head_ptr = '\0';
+
+    fputs(head, logDest);
+    if (logMsg) {
+        char msg[1024];
+        char* msgPtr;
+        vsnprintf(msg,1024, fmt, ap);  // create message
+
+        // detect multiple lines in message and indent each line by 4 spaces.
+        char* line = strtok_r(msg,"\n",&msgPtr);
+        while (line != NULL) {
+            fprintf(logDest,"    %s\n",line);
+            line = strtok_r(NULL,"\n",&msgPtr);
+        }
+    } else {
+        fputc('\n', logDest);
+    }
+}
+
+/*****************************************************************************
+    psLogMsg(): This routine sends the message, which is a printf style
+ string specified in the "..." argument, to the current message log
+ destination with the severity specified by the "level" argument.
+    Input:
+ name: Indicates the source of this log message.
+ level: The severity of this log message.
+ fmt: The printf-stype formatted string, followed by the arguments
+  to that string.
+ ... The arguments to the above printf-style string.
+    Output:
+ none
+    Return:
+ NULL
+ *****************************************************************************/
+void psLogMsg(const char *name, int level, const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    psLogMsgV(name, level, fmt, ap);
+    va_end(ap);
+}
+void psWarning(const char* name, const char* fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    psLogMsgV(name, PS_LOG_WARN, fmt, ap);
+    va_end(ap);
+}
Index: /branches/rel3/psLib/src/sys/psLogMsg.h
===================================================================
--- /branches/rel3/psLib/src/sys/psLogMsg.h	(revision 2163)
+++ /branches/rel3/psLib/src/sys/psLogMsg.h	(revision 2163)
@@ -0,0 +1,116 @@
+/** @file  psLogMsg.h
+ *  @brief Procedures for logging messages.
+ *  \ingroup LogTrace
+ *
+ *  This file will hold the prototypes for defining procedure which set
+ *  message log levels, messahe log formats, message log destinations, and
+ *  for generating the messages themselves.
+ *  @ingroup LogTrace
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-14 20:01:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_LOG_MSG_H)
+#define PS_LOG_MSG_H
+#include <stdarg.h>
+#include <stdbool.h>
+
+/** @addtogroup LogTrace
+ *  @{
+ */
+
+/** This procedure sets the destination for future log messages.  Currently
+ *  the destination is specified by an integer which can have the following
+ *  pre-defined values: PS_LOG_NONE, PS_LOG_TO_STDOUT, and PS_LOG_TO_STDERR.
+ *  In future versions, this procedure will take a character string as an
+ *  argument which can specify more general log destinations.
+ *
+ *  @return int     true if set successfully, otherwise false.
+ */
+bool psLogSetDestination(
+    const char *dest                   ///< Specifies where to send messages.
+);
+
+/** This procedure sets the message level for future log messages.  Subsequent
+ *  log messages, with a log level of "mylevel", will only be logged if
+ *  "mylevel" is less than the current log level set by this procedure.
+ *  Ie. higher values set by this procedure will cause more log messages to
+ *  be displayed.
+ *
+ *  @return int    old logging level
+ */
+int psLogSetLevel(
+    int level                          ///< Specifies the system log level
+);
+
+/** This procedure sets the log format for future log messages.  The argument
+ *  must be a character string consistsing of the letters H (host), L
+ *  (level), M (message), N (name), and T (time).  The default is "THLNM".
+ *  Deleting a letter from the string will cause the associated information
+ *  to not be logged.
+ *
+ */
+void psLogSetFormat(
+    const char *fmt                    ///< Specifies the system log format
+);
+
+/** This procedure logs a message to the destination set by a prior
+ *  call to psLogSetDestination(), if myLevel is less than the level
+ *  specified by a prior call to psLogSetLevel().  The message is specified
+ *  with a printf-stype string an arguments.
+ *
+ */
+void psLogMsg(
+    const char *name,                  ///< name of the log source
+    int myLevel,                       ///< severity level of this log message
+    const char *fmt,                   ///< printf-style format command
+    ...
+);
+
+/** This procedure is functionally equivalent to psLogMsg(), except that
+ *  it takes a va_list as the message parameter, not a printf-style string.
+ *
+ */
+void psLogMsgV(
+    const char *name,                  ///< name of the log source
+    int myLevel,                       ///< severity level of this log message
+    const char *fmt,                   ///< printf-style format command
+    va_list ap                         ///< varargs argument list
+);
+
+///< Status codes for log messages
+enum {
+    PS_LOG_ABORT = 0,                  ///< log message is a critical error, perform an abort after printing
+    PS_LOG_ERROR,                      ///< log message is an error, but don't abort
+    PS_LOG_WARN,                       ///< log message is a warning
+    PS_LOG_INFO                        ///< log message is informational only
+};
+
+///< Destinations for log messages
+enum {
+    PS_LOG_NONE,                       ///< turn off logging
+    PS_LOG_TO_STDERR,                  ///< log to system's stderr
+    PS_LOG_TO_STDOUT                   ///< log to system's stdout
+};
+
+/** Logs a warning message.
+ *
+ *  This procedure logs a message to the destination set by a prior
+ *  call to psLogSetDestination(), This is equivalent to calling
+ *  psLogMsg with a level of PS_LOG_WARN.
+ *
+ */
+void psWarning(
+    const char* name,
+    const char* fmt,
+    ...
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/sys/psMemory.c
===================================================================
--- /branches/rel3/psLib/src/sys/psMemory.c	(revision 2163)
+++ /branches/rel3/psLib/src/sys/psMemory.c	(revision 2163)
@@ -0,0 +1,695 @@
+/** @file  psMemory.c
+*
+*  @brief Contains the definitions for the memory management system
+*
+*  psMemory.h has additional information and documentation of the routines found in this file.
+*
+*  @author Robert DeSonia, MHPCC
+*  @author Robert Lupton, Princeton University
+*
+*  @version $Revision: 1.41 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-09-21 22:30:19 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#define PS_ALLOW_MALLOC                    // we're allowed to call malloc()
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psLogMsg.h"
+
+#include "psSysUtilsErrors.h"
+
+#define P_PS_MEMMAGIC (void *)0xdeadbeef   // Magic number in psMemBlock header
+
+#define P_PS_LARGE_BLOCK_SIZE 65536        // size where under, we try to recycle
+
+static int checkMemBlock(const psMemBlock* m, const char *funcName);
+static psMemBlock* lastMemBlockAllocated = NULL;
+static pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t memIdMutex = PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_mutex_t recycleMemBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
+
+static int recycleBins = 13;
+static int recycleBinSize[14] = {
+                                    8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, P_PS_LARGE_BLOCK_SIZE
+                                };
+
+// N.B. recycleBinSize should be terminated by P_PS_LARGE_BLOCK_SIZE (simplifies search loops)
+static psMemBlock* recycleMemBlockList[13] = {
+            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+        };
+
+#ifdef PS_MEM_DEBUG
+static psMemBlock* deadBlockList;       // a place to put dead memBlocks in debug mode.
+#endif
+
+/**
+ * Unique ID for allocated blocks
+ */
+static psMemoryId memid = 0;
+
+/**
+ *  Default memExhausted callback.
+ */
+static void *memExhaustedCallbackDefault(size_t size)
+{
+    void *ptr = NULL;
+
+    pthread_mutex_lock(&recycleMemBlockListMutex);
+    int level = recycleBins - 1;
+
+    while (level >= 0 && ptr == NULL) {
+        while (recycleMemBlockList[level] != NULL && ptr == NULL) {
+            psMemBlock* old = recycleMemBlockList[level];
+
+            recycleMemBlockList[level] = recycleMemBlockList[level]->nextBlock;
+            free(old);
+            ptr = malloc(size);
+        }
+        level--;
+    }
+    pthread_mutex_unlock(&recycleMemBlockListMutex);
+
+    return ptr;
+}
+
+static psMemExhaustedCallback memExhaustedCallback = memExhaustedCallbackDefault;
+
+psMemExhaustedCallback psMemExhaustedCallbackSet(psMemExhaustedCallback func)
+{
+    psMemExhaustedCallback old = memExhaustedCallback;
+
+    if (func != NULL) {
+        memExhaustedCallback = func;
+    } else {
+        memExhaustedCallback = memExhaustedCallbackDefault;
+    }
+
+    return old;
+}
+
+static void memProblemCallbackDefault(const psMemBlock* ptr, const char *file, int lineno)
+{
+    if (ptr->refCounter < 1) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "memProblemCallbackDefault", false, PS_ERR_MEMORY_CORRUPTION,
+                   PS_ERRORTEXT_psMemory_MULTIPLE_FREE,
+                   ptr->id, ptr->file, ptr->lineno, file, lineno);
+    }
+
+    if (lineno > 0) {
+        psAbort(__func__, "Detected a problem in the memory system at %s:%d", file, lineno);
+    }
+}
+static psMemProblemCallback memProblemCallback = memProblemCallbackDefault;
+
+psMemProblemCallback psMemProblemCallbackSet(psMemProblemCallback func)
+{
+    psMemProblemCallback old = memProblemCallback;
+
+    if (func != NULL) {
+        memProblemCallback = func;
+    } else {
+        memProblemCallback = memProblemCallbackDefault;
+    }
+
+    return old;
+}
+
+/*
+ * And now the I-want-to-be-informed callbacks
+ *
+ * Call the callbacks when these IDs are allocated/freed
+ */
+psMemoryId p_psMemAllocateID = 0;       // notify user this block is allocated
+psMemoryId p_psMemFreeID = 0;   // notify user this block is freed
+
+psMemoryId psMemAllocateCallbackSetID(psMemoryId id)
+{
+    psMemoryId old = p_psMemAllocateID;
+
+    p_psMemAllocateID = id;
+
+    return old;
+}
+
+psMemoryId psMemFreeCallbackSetID(psMemoryId id)
+{
+    psMemoryId old = p_psMemFreeID;
+
+    p_psMemFreeID = id;
+
+    return old;
+}
+
+/*
+ * Default callback for both allocate and free. Note that the
+ * value of p_psMemAllocateID/p_psMemFreeID is incremented
+ * by the return value (so returning 0 means that the callback
+ * isn't resignalled)
+ */
+static psMemoryId memAllocateCallbackDefault(const psMemBlock* ptr)
+{
+    static psMemoryId incr = 0; // "p_psMemAllocateID += incr"
+
+    return incr;
+}
+
+static psMemoryId memFreeCallbackDefault(const psMemBlock* ptr)
+{
+    static psMemoryId incr = 0; // "p_psMemFreeID += incr"
+
+    return incr;
+}
+
+/*
+ * The default callbacks, and the routines to change them
+ */
+static psMemAllocateCallback memAllocateCallback = memAllocateCallbackDefault;
+static psMemFreeCallback memFreeCallback = memFreeCallbackDefault;
+
+psMemAllocateCallback psMemAllocateCallbackSet(psMemAllocateCallback func)
+{
+    psMemFreeCallback old = memAllocateCallback;
+
+    if (func != NULL) {
+        memAllocateCallback = func;
+    } else {
+        memAllocateCallback = memAllocateCallbackDefault;
+    }
+
+    return old;
+}
+
+psMemFreeCallback psMemFreeCallbackSet(psMemFreeCallback func)
+{
+    psMemFreeCallback old = memFreeCallback;
+
+    if (func != NULL) {
+        memFreeCallback = func;
+    } else {
+        memFreeCallback = memFreeCallbackDefault;
+    }
+
+    return old;
+}
+
+/*
+ * Return memory ID counter for next block to be allocated
+ */
+psMemoryId psMemGetId(void)
+{
+    psMemoryId id;
+
+    pthread_mutex_lock(&memIdMutex);
+    id = memid + 1;
+    pthread_mutex_unlock(&memIdMutex);
+
+    return id;
+}
+
+/*
+ * Routines to check the consistency of the allocated and/or free memory arena
+ *
+ * N.b. If the block wasn't allocated by psAlloc, it will appear corrupted
+ */
+
+static int checkMemBlock(const psMemBlock* m, const char *funcName)
+{
+    // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked,
+    // we shouldn't call such things as p_psAlloc/p_psFree here.
+
+    if (m == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "checkMemBlock", true, PS_ERR_MEMORY_CORRUPTION,
+                   PS_ERRORTEXT_psMemory_NULL_BLOCK);
+        return 1;
+    }
+
+    if (m->refCounter == 0) {
+        // using an unreferenced block of memory, are you?
+        psErrorMsg(PS_ERRORNAME_DOMAIN "checkMemBlock", true, PS_ERR_MEMORY_CORRUPTION,
+                   PS_ERRORTEXT_psMemory_DEREF_BLOCK_USE,
+                   m->id);
+        return 1;
+    }
+
+    if (m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "checkMemBlock", true, PS_ERR_MEMORY_CORRUPTION,
+                   PS_ERRORTEXT_psMemory_UNDERFLOW,
+                   m->id);
+        return 1;
+    }
+    if (*(void **)((int8_t *) (m + 1) + m->userMemorySize) != P_PS_MEMMAGIC) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "checkMemBlock", true, PS_ERR_MEMORY_CORRUPTION,
+                   PS_ERRORTEXT_psMemory_OVERFLOW,
+                   m->id);
+        return 1;
+    }
+
+    return 0;
+}
+
+int psMemCheckCorruption(bool abort_on_error)
+{
+    int nbad = 0;               // number of bad blocks
+    bool failure = false;
+
+    // get exclusive access to the memBlock list to avoid it changing on us while we use it.
+    //    pthread_mutex_lock(&memBlockListMutex);
+
+    for (psMemBlock* iter = lastMemBlockAllocated; iter != NULL; iter = iter->nextBlock) {
+        pthread_mutex_unlock(&memBlockListMutex);
+        failure = checkMemBlock(iter, __func__);
+        pthread_mutex_lock(&memBlockListMutex);
+        if ( failure ) {
+            nbad++;
+
+            memProblemCallback(iter, __func__, __LINE__);
+
+            if (abort_on_error) {
+                // release the lock on the memblock list
+                pthread_mutex_unlock(&memBlockListMutex);
+                psAbort(__func__, "Detected memory corruption");
+                return nbad;
+            }
+        }
+    }
+
+    // release the lock on the memblock list
+    pthread_mutex_unlock(&memBlockListMutex);
+    return nbad;
+}
+
+void *p_psAlloc(size_t size, const char *file, int lineno)
+{
+
+    psMemBlock* ptr = NULL;
+
+    // memory is of the size I want to bother recycling?
+    if (size < P_PS_LARGE_BLOCK_SIZE) {
+        // find the bin we need.
+        int level = 0;
+
+        while (size > recycleBinSize[level]) {
+            level++;
+        }
+        // Are we in one of the bins
+        if (level < recycleBins) {
+
+            size = recycleBinSize[level];  // round-up size to next sized bin.
+
+            pthread_mutex_lock(&recycleMemBlockListMutex);
+
+            if (recycleMemBlockList[level] != NULL) {
+                ptr = recycleMemBlockList[level];
+                recycleMemBlockList[level] = ptr->nextBlock;
+                if (recycleMemBlockList[level] != NULL) {
+                    recycleMemBlockList[level]->previousBlock = NULL;
+                }
+                size = ptr->userMemorySize;
+            }
+
+            pthread_mutex_unlock(&recycleMemBlockListMutex);
+        }
+    }
+
+    if (ptr == NULL) {
+        ptr = malloc(sizeof(psMemBlock) + size + sizeof(void *));
+
+        if (ptr == NULL) {
+            ptr = memExhaustedCallback(size);
+            if (ptr == NULL) {
+                psAbort(__func__, "Failed to allocate %u bytes at %s:%d", size, file, lineno);
+            }
+        }
+
+        ptr->startblock = P_PS_MEMMAGIC;
+        ptr->endblock = P_PS_MEMMAGIC;
+        ptr->userMemorySize = size;
+        pthread_mutex_init(&ptr->refCounterMutex, NULL);
+    }
+    // increment the memory id safely.
+    pthread_mutex_lock(&memBlockListMutex);
+    *(psMemoryId* ) & ptr->id = ++memid;
+    pthread_mutex_unlock(&memBlockListMutex);
+
+    ptr->file = file;
+    ptr->freeFcn = NULL;
+    ptr->persistent = false;
+    *(unsigned int *)&ptr->lineno = lineno;
+    *(void **)((int8_t *) (ptr + 1) + size) = P_PS_MEMMAGIC;
+    ptr->previousBlock = NULL;
+
+    ptr->refCounter = 1;                   // one user so far
+
+    // need exclusive access of the memory block list now...
+    pthread_mutex_lock(&memBlockListMutex);
+
+    // insert the new block to the front of the memBlock linked-list
+    ptr->nextBlock = lastMemBlockAllocated;
+    if (ptr->nextBlock != NULL) {
+        ptr->nextBlock->previousBlock = ptr;
+    }
+    lastMemBlockAllocated = ptr;
+
+    pthread_mutex_unlock(&memBlockListMutex);
+
+    // Did the user ask to be informed about this allocation?
+    if (ptr->id == p_psMemAllocateID) {
+        p_psMemAllocateID += memAllocateCallback(ptr);
+    }
+    // And return the user the memory that they allocated
+    return ptr + 1;                        // user memory
+}
+
+void *p_psRealloc(void *vptr, size_t size, const char *file, int lineno)
+{
+    if (vptr == NULL) {
+        return p_psAlloc(size, file, lineno);
+    } else {
+        psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+        bool isBlockLast = false;
+
+        if (checkMemBlock(ptr, __func__) != 0) {
+            memProblemCallback(ptr, file, lineno);
+            psAbort(file, "Realloc detected a memory corruption (id %ld @ %s:%d).",
+                    ptr->id, ptr->file, ptr->lineno);
+        }
+
+        pthread_mutex_lock(&memBlockListMutex);
+
+        isBlockLast = (ptr == lastMemBlockAllocated);
+
+        ptr = (psMemBlock* ) realloc(ptr, sizeof(psMemBlock) + size + sizeof(void *));
+
+        if (ptr == NULL) {
+            ptr = memExhaustedCallback(size);
+            if(ptr == NULL) {
+                psAbort(__func__, "Failed to reallocate %ld bytes at %s:%d", size, file, lineno);
+            }
+        }
+
+        ptr->userMemorySize = size;
+        *(void **)((int8_t *) (ptr + 1) + size) = P_PS_MEMMAGIC;
+
+        if (isBlockLast) {
+            lastMemBlockAllocated = ptr;
+        }
+        // the block location may have changed, so fix the linked list addresses.
+        if (ptr->nextBlock != NULL) {
+            ptr->nextBlock->previousBlock = ptr;
+        }
+        if (ptr->previousBlock != NULL) {
+            ptr->previousBlock->nextBlock = ptr;
+        }
+
+        pthread_mutex_unlock(&memBlockListMutex);
+
+        // Did the user ask to be informed about this allocation?
+        if (ptr->id == p_psMemAllocateID) {
+            p_psMemAllocateID += memAllocateCallback(ptr);
+        }
+
+        return ptr + 1;                    // usr memory
+    }
+}
+
+void p_psFree(void *vptr, const char *file, int lineno)
+{
+    if (vptr == NULL) {
+        return;
+    }
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+    if (ptr->refCounter < 1) {
+        psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psFree",PS_ERR_MEMORY_DEREF_USAGE,true,
+                   PS_ERRORTEXT_psMemory_MULTIPLE_FREE,
+                   ptr->id, ptr->file, ptr->lineno, file, lineno);
+
+        return;
+    }
+    (void)p_psMemDecrRefCounter(vptr, file, lineno);    // this handles the free, if required.
+}
+
+/*
+ * Check for memory leaks.
+ */
+int psMemCheckLeaks(psMemoryId id0, psMemBlock* ** arr, FILE * fd)
+{
+    int nleak = 0;
+    int j = 0;
+    psMemBlock* topBlock = lastMemBlockAllocated;
+
+    pthread_mutex_lock(&memBlockListMutex);
+
+    for (psMemBlock* iter = topBlock; iter != NULL; iter = iter->nextBlock) {
+        if ( (iter->refCounter > 0) &&
+                (! iter->persistent) &&
+                (iter->id >= id0)) {
+
+            nleak++;
+
+            if (fd != NULL) {
+                if (nleak == 1) {
+                    fprintf(fd, "   %20s:line ID\n", "file");
+                }
+
+                fprintf(fd, "   %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id);
+            }
+        }
+    }
+
+    pthread_mutex_unlock(&memBlockListMutex);
+
+    if (nleak == 0 || arr == NULL) {
+        return nleak;
+    }
+
+    *arr = p_psAlloc(nleak * sizeof(psMemBlock), __FILE__, __LINE__);
+    pthread_mutex_lock(&memBlockListMutex);
+
+    for (psMemBlock* iter = topBlock; iter != NULL; iter = iter->nextBlock) {
+        if ( (iter->refCounter > 0) &&
+                (! iter->persistent) &&
+                (iter->id >= id0)) {
+
+            (*arr)[j++] = iter;
+            if (j == nleak) {              // found them all
+                break;
+            }
+        }
+    }
+
+    pthread_mutex_unlock(&memBlockListMutex);
+
+    return nleak;
+}
+
+/*
+ * Reference counting APIs
+ */
+// return refCounter
+psReferenceCount psMemGetRefCounter(void *vptr)
+{
+    psMemBlock* ptr;
+    unsigned int refCount;
+
+    if (vptr == NULL) {
+        return 0;
+    }
+
+    ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    pthread_mutex_lock(&ptr->refCounterMutex);
+    refCount = ptr->refCounter;
+    pthread_mutex_unlock(&ptr->refCounterMutex);
+
+    return refCount;
+}
+
+// increment and return refCounter
+void *p_psMemIncrRefCounter(void *vptr, const char *file, int lineno)
+{
+    psMemBlock* ptr;
+
+    if (vptr == NULL) {
+        return vptr;
+    }
+
+    ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__)) {
+        memProblemCallback(ptr, file, lineno);
+    }
+
+    pthread_mutex_lock(&ptr->refCounterMutex);
+    ptr->refCounter++;
+    pthread_mutex_unlock(&ptr->refCounterMutex);
+
+    return vptr;
+}
+
+// decrement and return refCounter
+void *p_psMemDecrRefCounter(void *vptr, const char *file, int lineno)
+{
+    if (vptr == NULL) {
+        return NULL;
+    }
+
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, file, lineno);
+        return NULL;
+    }
+
+    pthread_mutex_lock(&ptr->refCounterMutex);
+
+    if (ptr->refCounter > 1) {
+        ptr->refCounter--;                 // multiple references, just decrement the count.
+        pthread_mutex_unlock(&ptr->refCounterMutex);
+
+    } else {
+        pthread_mutex_unlock(&ptr->refCounterMutex);
+
+        // Did the user ask to be informed about this deallocation?
+        if (ptr->id == p_psMemFreeID) {
+            p_psMemFreeID += memFreeCallback(ptr);
+        }
+
+        if (ptr->freeFcn != NULL) {
+            ptr->freeFcn(vptr);
+        }
+
+        pthread_mutex_lock(&memBlockListMutex);
+
+        // cut the memBlock out of the memBlock list
+        if (ptr->nextBlock != NULL) {
+            ptr->nextBlock->previousBlock = ptr->previousBlock;
+        }
+        if (ptr->previousBlock != NULL) {
+            ptr->previousBlock->nextBlock = ptr->nextBlock;
+        }
+        if (lastMemBlockAllocated == ptr) {
+            lastMemBlockAllocated = ptr->nextBlock;
+        }
+
+        pthread_mutex_unlock(&memBlockListMutex);
+
+        // do we need to recycle?
+        if (ptr->userMemorySize < P_PS_LARGE_BLOCK_SIZE) {
+
+            int level = 1;
+
+            while (ptr->userMemorySize >= recycleBinSize[level]) {
+                level++;
+            }
+            level--;
+
+            ptr->refCounter = 0;
+            ptr->previousBlock = NULL;
+
+            pthread_mutex_lock(&recycleMemBlockListMutex);
+            ptr->nextBlock = recycleMemBlockList[level];
+            if (recycleMemBlockList[level] != NULL) {
+                recycleMemBlockList[level]->previousBlock = ptr;
+            }
+            recycleMemBlockList[level] = ptr;
+            pthread_mutex_unlock(&recycleMemBlockListMutex);
+
+        } else {
+            // memory is larger than I want to recycle.
+            #ifdef PS_MEM_DEBUG
+            (void)p_psRealloc(vptr, 0, file, lineno);
+            ptr->previousBlock = NULL;
+            ptr->nextBlock = deadBlockList;
+            if (deadBlockList != NULL) {
+                deadBlockList->previous = ptr;
+            }
+            deadBlockList = ptr;
+            #else
+
+            pthread_mutex_destroy(&ptr->refCounterMutex);
+            free(ptr);
+            #endif
+
+        }
+
+        vptr = NULL;                       // since we freed it, make sure we return NULL.
+    }
+
+    return vptr;
+}
+
+void p_psMemSetDeallocator(void *vptr, psFreeFcn freeFcn)
+{
+    if (vptr == NULL) {
+        return;
+    }
+
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    ptr->freeFcn = freeFcn;
+
+}
+psFreeFcn p_psMemGetDeallocator(void *vptr)
+{
+    if (vptr == NULL) {
+        return NULL;
+    }
+
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    return ptr->freeFcn;
+}
+
+bool p_psMemGetPersistent(void *vptr)
+{
+    if (vptr == NULL) {
+        return NULL;
+    }
+
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    return ptr->persistent;
+}
+
+void p_psMemSetPersistent(void *vptr,bool value)
+{
+    if (vptr == NULL) {
+        return;
+    }
+
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    ptr->persistent = value;
+}
Index: /branches/rel3/psLib/src/sys/psMemory.h
===================================================================
--- /branches/rel3/psLib/src/sys/psMemory.h	(revision 2163)
+++ /branches/rel3/psLib/src/sys/psMemory.h	(revision 2163)
@@ -0,0 +1,445 @@
+/** @file  psMemory.h
+ *
+ *  @brief Contains the definitions for the memory management system
+ *
+ *  This is the generic memory management system put inbetween the user's high level code and the OS-level
+ *  memory allocation routines.  This system adds such features as callback routines for memory error events,
+ *  tracing capabilities, and reference counting.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Robert Lupton, Princeton University
+ *
+ *  @ingroup MemoryManagement
+ *
+ *  @version $Revision: 1.30 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-14 23:48:25 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#if !defined(PS_MEMORY_H)
+#define PS_MEMORY_H
+
+#include <stdio.h>                     // needed for FILE
+#include <stdbool.h>
+#include <pthread.h>                   // we need a mutex to make this stuff thread safe.
+
+/** @addtogroup MemoryManagement
+ *  @{
+ */
+
+/**
+ *  @addtogroup memCallback Memory Callbacks
+ *
+ *  Routines dealing with the creating and setting of memory management callback functions.
+ */
+
+/**
+ *  @addtogroup memTracing Memory Tracing
+ *
+ *  Routines dealing with memory tracing and corruption checking.
+ */
+
+/**
+ *  @addtogroup memRefCount Reference Count
+ *
+ *  Routines dealing with the reference counting of allocated buffers.
+ */
+
+/// typedef for memory identification numbers.  Guaranteed to be some variety of integer.
+typedef unsigned long psMemoryId;
+
+/// typedef for a memory block's reference count. Guaranteed to be some variety of integer.
+typedef unsigned long psReferenceCount;
+
+/// typedef for deallocator.
+typedef void (*psFreeFcn) (void *ptr);
+
+/** Book-keeping data for storage allocator.
+ *  N.b. sizeof(psMemBlock) must be chosen such that if ptr is a pointer
+ *  returned by malloc, then ((char *)ptr + sizeof(psMemBlock)) is properly
+ *  aligned for all storage types.
+ */
+typedef struct psMemBlock
+{
+    const void *startblock;            ///< initialised to p_psMEMMAGIC
+    struct psMemBlock* previousBlock;  ///< previous block in allocation list
+    struct psMemBlock* nextBlock;      ///< next block allocation list
+    psFreeFcn freeFcn;                 ///< deallocator.  If NULL, use generic deallocation.
+    size_t userMemorySize;             ///< the size of the user-portion of the memory block
+    const psMemoryId id;               ///< a unique ID for this allocation
+    const char *file;                  ///< set from __FILE__ in e.g. p_psAlloc
+    const int lineno;                  ///< set from __LINE__ in e.g. p_psAlloc
+    pthread_mutex_t refCounterMutex;   ///< mutex to ensure exclusive access to reference counter
+    psReferenceCount refCounter;       ///< how many times pointer is referenced
+    bool persistent;                   ///< marks if this non-user persistent data like error stack, etc.
+    const void *endblock;              ///< initialised to p_psMEMMAGIC
+}
+psMemBlock;
+
+/** prototype of a basic callback used by memory functions
+ *
+ *  @see psMemAllocateCallbackSet
+ *  @ingroup memCallback
+ */
+typedef psMemoryId(*psMemAllocateCallback) (
+    const psMemBlock* ptr              ///< the psMemBlock just allocated
+);
+
+/** prototype of memory free callback used by memory functions
+ *
+ *  @see psMemFreeCallbackSet
+ *  @ingroup memCallback
+ */
+typedef psMemoryId(*psMemFreeCallback) (
+    const psMemBlock* ptr              ///< the psMemBlock being freed
+);
+
+/** prototype of a callback used in error conditions
+ *
+ *  This callback should not try to call psAlloc or psFree.
+ *
+ *  @see psMemProblemCallbackSet
+ *  @ingroup memCallback
+ */
+typedef void (*psMemProblemCallback) (
+    const psMemBlock* ptr,             ///< the pointer to the problematic memory block.
+    const char *file,                  ///< the file in which the problem originated
+    int lineno                         ///< the line number in which the problem originated
+);
+
+/** prototype of a callback function used when memory runs out
+ *
+ *  @return void* pointer to requested buffer of the size size_t, or NULL if memory could not
+ *          be found.
+ *
+ *  @see psMemExhaustedCallbackSet
+ *  @ingroup memCallback
+ */
+typedef void *(*psMemExhaustedCallback) (
+    size_t size                        ///< the size of buffer required
+);
+
+/** Memory allocation.  This operates much like malloc(), but is guaranteed to return a non-NULL value.
+ *
+ *  @return void* pointer to the allocated buffer. This will not be NULL.
+ *  @see psFree 
+ */
+#ifdef DOXYGEN
+void *psAlloc(size_t size       ///< Size required
+             );
+#else
+
+void *p_psAlloc(size_t size,    ///< Size required
+                const char *file,       ///< File of call
+                int lineno      ///< Line number of call
+               );
+
+/// Memory allocation. psAlloc sends file and line number to p_psAlloc.
+#define psAlloc(size) p_psAlloc(size, __FILE__, __LINE__)
+#endif
+
+/** Set the deallocator routine
+ *
+ *  A deallocator routine can optionally be assigned to a memory block to 
+ *  ensure that associated memory blocks also get freed, e.g., memory buffers
+ *  referenced within a struct.
+ *
+ */
+void p_psMemSetDeallocator(
+    void *ptr,                         ///< the memory block to operate on
+    psFreeFcn freeFcn                  ///< the function to be executed at deallocation
+);
+
+/** Get the deallocator routine
+ *
+ *  This function returns the deallocator for a memory block.  A deallocator 
+ *  routine can optionally be assigned to a memory block to ensure that 
+ *  associated memory blocks also get freed, e.g., memory buffers referenced 
+ *  within a struct.  
+ *
+ *  @return psFreeFcn    the routine to be called at deallocation.
+ */
+psFreeFcn p_psMemGetDeallocator(
+    void *ptr                          ///< the memory block
+);
+
+/** Set the memory as persistent so that it is ignored when detecting memory leaks.
+ *
+ *  Used to mark a memory block as persistent data within the library, 
+ *  i.e., non user-level data used to hold psLib's state or cache data.  Such
+ *  examples of this class of memory is psTrace's trace-levels and dynamic
+ *  error codes.
+ *
+ *  Memory marked as persistent is excluded from memory leak checks.
+ *
+ */
+void p_psMemSetPersistent(
+    void *ptr,                         ///< the memory block to operate on
+    bool value                         ///< true if memory is persistent, otherwise false
+);
+
+/** Get the memory's persistent flag.
+ *
+ *  Checks if a memory block has been marked as persistent by 
+ *  p_psMemSetPresistent.
+ *
+ *  Memory marked as persistent is excluded from memory leak checks.
+ *
+ *  @return bool    true if memory is marked persistent, otherwise false.
+ */
+bool p_psMemGetPersistent(
+    void *ptr                          ///< the memory block to check.
+);
+
+
+/** Memory re-allocation.  This operates much like realloc(), but is guaranteed to return a non-NULL value.
+ *
+ *  @return void* pointer to resized buffer. This will not be NULL.
+ *  @see psAlloc, psFree
+ */
+#ifdef DOXYGEN
+void *psRealloc(
+    void *ptr                          ///< Pointer to re-allocate
+    size_t size,                       ///< Size required
+);
+#else
+
+void *p_psRealloc(
+    void *ptr,                         ///< Pointer to re-allocate
+    size_t size,                       ///< Size required
+    const char *file,                  ///< File of call
+    int lineno                         ///< Line number of call
+);
+
+/// Memory re-allocation.  psRealloc sends file and line number to p_psRealloc.
+#define psRealloc(ptr, size) p_psRealloc(ptr, size, __FILE__, __LINE__)
+
+#endif
+
+/** Free memory.  This operates much like free().
+ *
+ *  @see psAlloc, psRealloc
+ */
+#ifdef DOXYGEN
+void psFree(
+    void *ptr,                         ///< Pointer to free, if NULL, function returns immediately.
+);
+#else
+
+void p_psFree(
+    void *ptr,                        ///< Pointer to free
+    const char *file,                 ///< File of call
+    int lineno                        ///< Line number of call
+);
+
+/// Free memory.  psFree sends file and line number to p_psFree.
+#define psFree(size) p_psFree(size, __FILE__, __LINE__)
+
+#endif
+
+/** Check for memory leaks.  This scans for allocated memory buffers not freed with an ID not less than id0.
+ *  This is used to check for memory leaks by:
+ *      -# before a block of code to be checked, store the current ID count via psGetMemId
+ *      -# after the block of code to be checked, call this function using the ID stored above.  If all
+ *         memory in the block that was allocated has been freed, this call should output nothing and
+ *         return 0.
+ *
+ *  If memory leaks are found, the Memory Problem callback will be called as well.
+ *
+ *  return int  number of memory blocks found as 'leaks', i.e., the number of currently allocated memory
+ *              blocks above id0 that have not been freed.
+ *  @see psAlloc, psFree, psgetMemId, psMemProblemCallbackSet
+ *  @ingroup memTracing
+ */
+int psMemCheckLeaks(
+    psMemoryId id0,                    ///< don't list blocks with id < id0
+    psMemBlock* ** arr,                ///< pointer to array of pointers to leaked blocks, or NULL
+    FILE * fd                          ///< print list of leaks to fd (or NULL)
+);
+
+/** Check for memory corruption.  Scans all currently allocated memory buffers and checks for corruptions,
+ *  i.e., invalid markers that signify a buffer under/overflow.
+ *
+ *  @ingroup memTracing
+ */
+int psMemCheckCorruption(
+    bool abort_on_error                ///< Abort on detecting corruption?
+);
+
+/** Return reference counter
+ *
+ *  @ingroup memRefCount
+ */
+psReferenceCount psMemGetRefCounter(
+    void *vptr                         ///< Pointer to get refCounter for
+);
+
+/** Increment reference counter and return the pointer
+ *
+ *  @ingroup memRefCount
+ */
+#ifdef DOXYGEN
+void *psMemIncrRefCounter(
+    void *vptr                         ///< Pointer to increment refCounter, and return
+);
+#else
+
+void *p_psMemIncrRefCounter(
+    void *vptr,                        ///< Pointer to increment refCounter, and return
+    const char *file,                  ///< File of call
+    int lineno                         ///< Line number of call
+);
+
+#define psMemIncrRefCounter(vptr) p_psMemIncrRefCounter(vptr, __FILE__, __LINE__)
+#endif
+
+/** Decrement reference counter and return the pointer
+ *
+ *  @ingroup memRefCount
+ *
+ *  @return void*    the pointer deremented in refCount, or NULL if pointer is 
+ *                   fully dereferenced.
+ */
+#ifdef DOXYGEN
+void* psMemDecrRefCounter(
+    void* vptr                         ///< Pointer to decrement refCounter, and return
+);
+#else
+
+void *p_psMemDecrRefCounter(
+    void *vptr,                        ///< Pointer to decrement refCounter, and return
+    const char *file,                  ///< File of call
+    int lineno                         ///< Line number of call
+);
+
+#define psMemDecrRefCounter(vptr) p_psMemDecrRefCounter(vptr, __FILE__, __LINE__)
+#endif
+
+/** Set callback for problems.
+ *
+ *  At various occasions, the memory manager can check the state of the memory 
+ *  stack. If any of these checks discover that the memory stack is corrupted,
+ *  the psMemProblemCallback is called.
+ 
+ *  @ingroup memCallback
+ *
+ *  @return psMemProblemCallback       old psMemProblemCallback function
+ */
+psMemProblemCallback psMemProblemCallbackSet(
+    psMemProblemCallback func          ///< Function to run at memory problem detection
+);
+
+/** Set callback for out-of-memory.
+ *
+ *  If not enough memory is available to satisfy a request by psAlloc or 
+ *  psRealloc, these functions attempt to find an alternative solution by 
+ *  calling the psMemExhaustedCallback, a function which may be set by the 
+ *  programmer in appropriate circumstances, rather than immediately fail. 
+ *  The typical use of such a feature may be when a program needs a large 
+ *  chunk of memory to do an operation, but the exact size is not critical. 
+ *  This feature gives the programmer the opportunity to make a smaller 
+ *  request and try again, limiting the size of the operating buffer.
+ *
+ *  @ingroup memCallback
+ *
+ *  @return psMemExhaustedCallback     old psMemExhaustedCallback function
+ */
+psMemExhaustedCallback psMemExhaustedCallbackSet(
+    psMemExhaustedCallback func        ///< Function to run at memory exhaustion
+);
+
+/** Set call back for when a particular memory block is allocated
+ *
+ *  A private variable, p_psMemAllocateID, can be used to trace the allocation 
+ *  and freeing of specific memory blocks. If p_psMemAllocateID is set and a 
+ *  memory block with that ID is allocated, psMemAllocateCallback is called 
+ *  just before memory is returned to the calling function.
+ *
+ *  @ingroup memCallback
+ *
+ *  @return psMemAllocateCallback      old psMemAllocateCallback function
+ */
+psMemAllocateCallback psMemAllocateCallbackSet(
+    psMemAllocateCallback func       ///< Function to run at memory allocation of specific mem block
+);
+
+/** Set call back for when a particular memory block is freed
+ *
+ *  A private variable, p_psMemFreeID, can be used to trace the freeing of 
+ *  specific memory blocks. If p_psMemFreeID is set and the memory block with 
+ *  the ID is about to be freed, the psMemFreeCallback callback is called just
+ *  before the memory block is freed.
+ *
+ *  @ingroup memCallback
+ *
+ *  @return psMemFreeCallback          old psMemFreeCallback function
+ */
+psMemFreeCallback psMemFreeCallbackSet(
+    psMemFreeCallback func             ///< Function to run at memory free of specific mem block
+);
+
+/** get next memory ID
+ *
+ *  @ingroup memCallback
+ *
+ *  @return psMemoryId                 the next memory ID to be used
+ */
+psMemoryId psMemGetId(void);
+
+/** set p_psMemAllocateID to specific id
+ *
+ *  A private variable, p_psMemAllocateID, can be used to trace the allocation 
+ *  and freeing of specific memory blocks. If p_psMemAllocateID is set and a 
+ *  memory block with that ID is allocated, psMemAllocateCallback is called 
+ *  just before memory is returned to the calling function.
+ *
+ *  @ingroup memCallback
+ *
+ *  @return psMemoryId       
+ *
+ *  @see psMemAllocateCallbackSet    
+ */
+psMemoryId psMemAllocateCallbackSetID(
+    psMemoryId id                      ///< ID to set
+);
+
+/** set p_psMemFreeID to id
+ *
+ *  A private variable, p_psMemFreeID, can be used to trace the freeing of 
+ *  specific memory blocks. If p_psMemFreeID is set and the memory block with 
+ *  the ID is about to be freed, the psMemFreeCallback callback is called just
+ *  before the memory block is freed.
+ *
+ *  @ingroup memCallback
+ *
+ *  @return psMemoryId                 the old p_psMemFreeID
+ *
+ *  @see psMemFreeCallbackSet
+ */
+psMemoryId psMemFreeCallbackSetID(
+    psMemoryId id                      ///< ID to set
+);
+
+//@} End of Memory Management Functions
+
+#ifndef DOXYGEN
+
+/*
+ * Ensure that any program using malloc/realloc/free will fail to compile
+ */
+#ifndef PS_ALLOW_MALLOC
+#ifdef __GNUC__
+#pragma GCC poison malloc realloc calloc free
+#else
+#define malloc(S)       _Pragma("error Use of malloc is not allowed.  Use psAlloc instead.")
+#define realloc(P,S)    _Pragma("error Use of realloc is not allowed.  Use psRealloc instead.")
+#define calloc(S)       _Pragma("error Use of calloc is not allowed.  Use psAlloc instead.")
+#define free(P)         _Pragma("error Use of free is not allowed.  Use psFree instead.")
+#endif
+#endif
+
+#endif
+// doxygen skip
+
+#endif // end of header file
Index: /branches/rel3/psLib/src/sys/psString.c
===================================================================
--- /branches/rel3/psLib/src/sys/psString.c	(revision 2163)
+++ /branches/rel3/psLib/src/sys/psString.c	(revision 2163)
@@ -0,0 +1,56 @@
+
+/** @file  psString.c
+ *
+ *  @brief Contains the definition of string utility functions
+ *
+ *  String utility functions defined shall provide basic string copying
+ *  capabilities while using the preferred memory management utilities.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-06 01:05:41 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "psString.h"
+#include "psMemory.h"
+#include "psError.h"
+
+#include "psSysUtilsErrors.h"
+
+char *psStringCopy(const char *str)
+{
+    // Allocate memory using psAlloc function
+    // Copy input string to memory just allocated
+    // Return the copy
+    return strcpy(psAlloc(strlen(str) + 1), str);
+}
+
+char *psStringNCopy(const char *str, int nChar)
+{
+    char *returnValue = NULL;
+
+    // Check the number of characters to copy is non-negative
+    if (nChar < 0) {
+        // Log error message and return NULL
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psStringNCopy", PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psString_NCHAR_NEGATIVE,
+                   nChar);
+        return NULL;
+    }
+    // Allocate memory using psAlloc function - nChar bytes
+    // Copy input string to memory allocated up to nChar characters
+    // Return the copy
+    returnValue = strncpy(psAlloc((size_t) nChar + 1), str, (size_t) nChar);
+
+    // Ensure the last byte is NULL character
+    if (nChar > 0) {
+        returnValue[nChar] = '\0';
+    }
+    // Return the string pointer
+    return returnValue;
+}
Index: /branches/rel3/psLib/src/sys/psString.h
===================================================================
--- /branches/rel3/psLib/src/sys/psString.h	(revision 2163)
+++ /branches/rel3/psLib/src/sys/psString.h	(revision 2163)
@@ -0,0 +1,70 @@
+/** @file  psString.h
+ *
+ *  @brief Contains the declarations of string utility functions
+ *
+ *  @ingroup SysUtils
+ *
+ *  String utility functions defined shall provide basic string copying
+ *  capabilities.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-10 01:55:34 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_STRING_H
+#define PS_STRING_H
+
+
+/** This macro will convert the argument to a quoted string */
+#define PS_STRING(S)  #S
+
+// Doxygen group tags
+
+/** @addtogroup SysUtils
+ *  @{
+ */
+
+/** Copies the input string
+ *
+ *  This function shall allocate memory to the length of the input string
+ *  plus one and copy the input string to the newly allocated memory.
+ *
+ *  @return char*      Copy of input string
+ *
+ */
+char *psStringCopy(
+    const char *str
+    /**< Input string of characters to copy */
+);
+
+/** Copies the input string up to the specified number of characters
+ *
+ *  This function shall allocate memory to the length specified by nChar
+ *  plus one and copy the input string to the newly allocated memory.
+ *  This function will only copy nChar bytes from the input to new string,
+ *  so if the input string is larger than nChar characters the copied
+ *  string will be a substring of the input string.  If the input string
+ *  is smaller than nChar bytes then the remaining bytes allocated will
+ *  be set to NULL.
+ *
+ *  @return  char* Copy of input string
+ *
+ */
+
+/*@null@*/
+
+char *psStringNCopy(
+    const char *str,
+    /**< Input string of characters to copy */
+
+    int nChar
+    /**< Number of bytes to allocate for string copy */
+);
+
+/* @} */// Doxygen - End of SystemGroup Functions
+
+#endif
Index: /branches/rel3/psLib/src/sys/psTrace.c
===================================================================
--- /branches/rel3/psLib/src/sys/psTrace.c	(revision 2163)
+++ /branches/rel3/psLib/src/sys/psTrace.c	(revision 2163)
@@ -0,0 +1,520 @@
+/** @file psTrace.c
+ *  \brief basic run-time trace facilities
+ *  \ingroup LogTrace
+ *
+ *  This file will hold the code for procedures to insert
+ *  trace messages into the code.
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.35 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-20 22:03:35 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/*****************************************************************************
+    NOTES:
+ In the SRD, higher trace levels correspond to a numerically lower trace
+ value in the code.  This is a bit confusing.  For example, a high-level
+ message might be something like "Begin Processing".  The module programmer
+ might give that a numerically low trace level, such as 1, so then any
+ non-zero trace level in that code component will display thatmessage.
+ 
+ We build a tree of trace components.  Every node in the tree has a
+ depth, which is it's distance from the root.  However, this is not
+ not the same thing as a node's "level", which corresponds to the
+ trace level of that node.
+ 
+I think the following is the correct behavior, but not sure:
+    PS_UNKNOWN_TRACE_LEVEL: We never set the level of a component to this
+    value.  This value is only used when psTraceGetLevel is called with
+    a bad component name, or if the component root is undefined, I think.
+ 
+    PS_DEFAULT_TRACE_LEVEL: This should only be used when adding the
+    intermediate components of a long name.  Ie. the "B" in .A.B.C
+ 
+ *****************************************************************************/
+
+#ifndef PS_NO_TRACE
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include "psMemory.h"
+#include "psTrace.h"
+#include "psString.h"
+#include "psError.h"
+#include "psLogMsg.h"
+
+#include "psSysUtilsErrors.h"
+
+static p_psComponent* cRoot = NULL; // The root of the trace component
+static FILE *traceFP = NULL;        // File destination for messages.
+
+static void componentFree(p_psComponent* comp);
+static p_psComponent* componentAlloc(const char *name, int level);
+
+/*****************************************************************************
+componentAlloc(): allocate memory for a new node, and initialize members.
+ *****************************************************************************/
+static p_psComponent* componentAlloc(const char *name, int level)
+{
+    p_psComponent* comp = psAlloc(sizeof(p_psComponent));
+
+    p_psMemSetPersistent(comp,true);
+    p_psMemSetDeallocator(comp, (psFreeFcn) componentFree);
+    comp->name = psStringCopy(name);
+    p_psMemSetPersistent((void*)comp->name,true);
+    comp->level = level;
+    comp->n = 0;
+    comp->subcomp = NULL;
+    return comp;
+}
+
+/*****************************************************************************
+componentFree(): free the current node in the root tree, and all children
+nodes as well.
+ *****************************************************************************/
+static void componentFree(p_psComponent* comp)
+{
+    if (comp == NULL) {
+        return;
+    }
+
+    if (comp->subcomp != NULL) {
+        for (int i = 0; i < comp->n; i++) {
+            p_psMemSetPersistent(comp->subcomp[i],false);
+            psFree(comp->subcomp[i]);
+        }
+        p_psMemSetPersistent(comp->subcomp,false);
+        psFree(comp->subcomp);
+    }
+
+    p_psMemSetPersistent((void*)comp->name,false);
+    psFree((void*)comp->name);
+}
+
+/*****************************************************************************
+initTrace(): simply initialize the component root tree.
+*****************************************************************************/
+static void initTrace(void)
+{
+    if (cRoot == NULL) {
+        cRoot = componentAlloc(".", PS_DEFAULT_TRACE_LEVEL);
+    }
+}
+
+/*****************************************************************************
+Set all trace levels to zero.
+ 
+XXX: Currently, no function calls this routine.
+ *****************************************************************************/
+void p_psTraceReset(p_psComponent* currentNode)
+{
+    int i = 0;
+
+    if (NULL == currentNode) {
+        return;
+    }
+
+    currentNode->level = 0;
+    for (i = 0; i < currentNode->n; i++) {
+        if (NULL == currentNode->subcomp[i]) {
+            psLogMsg(PS_ERRORNAME_DOMAIN "p_psTraceReset", PS_LOG_WARN,
+                     PS_ERRORTEXT_psTrace_NULL_SUBCOMPONENT,
+                     i, currentNode->name);
+        } else {
+            p_psTraceReset(currentNode->subcomp[i]);
+        }
+    }
+    return;
+}
+
+/*****************************************************************************
+Set all trace levels to zero.
+ *****************************************************************************/
+void psTraceReset()
+{
+    psFree(cRoot);
+    cRoot = NULL;
+}
+
+/*****************************************************************************
+componentAdd(): Adds the component named "addNodeName" to the root tree.
+ 
+NOTE: replace the call to strsep() with a call to strtok(), which conforms
+to ANSI-C.
+ *****************************************************************************/
+static bool componentAdd(const char *addNodeName, int level)
+{
+    int i = 0;                  // Loop index variable.
+    char name[strlen(addNodeName) + 1]; // buffer for writeable copy.
+    char *pname = name;
+    char *firstComponent = NULL;        // first component of name
+    p_psComponent* currentNode = cRoot;
+    int nodeExists = 0;
+
+    // XXX: Verify that this is the correct behavior.
+    if (strcmp("", addNodeName) == 0) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "componentAdd",PS_ERR_BAD_PARAMETER_NULL,true,
+                   PS_ERRORTEXT_psTrace_ADD_NULL_COMPONENT);
+        return false;
+    }
+
+    // Is this the root node? If so, simply set level and return.
+    if (strcmp(".", addNodeName) == 0) {
+        cRoot->level = level;
+        return true;
+    }
+
+    if (addNodeName[0] != '.') {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "componentAdd",PS_ERR_BAD_PARAMETER_VALUE,true,
+                   PS_ERRORTEXT_psTrace_MALFORMED_COMPONENT_NAME,
+                   addNodeName);
+        return false;
+    }
+
+    strcpy(name, addNodeName);
+    pname = &name[1];
+    // Iterate through the components of addNodeName.  Strip off the first
+    // component of the name, find that in the root tree, or add it if it
+    // does not exist, then move to the next component in the name.
+
+    while (pname != NULL) {
+        firstComponent = strsep(&pname, ".");
+        nodeExists = 0;
+        for (i = 0; i < currentNode->n; i++) {
+            if (strcmp(currentNode->subcomp[i]->name, firstComponent) == 0) {
+                currentNode = currentNode->subcomp[i];
+                nodeExists = 1;
+                if (pname == NULL) {
+                    currentNode->level = level;
+                }
+            }
+        }
+
+        if (nodeExists == 0) {
+            currentNode->subcomp = psRealloc(currentNode->subcomp,
+                                             (currentNode->n + 1) * sizeof(p_psComponent* ));
+            p_psMemSetPersistent(currentNode->subcomp,true);
+
+            currentNode->n = (currentNode->n) + 1;
+
+            if (pname == NULL) {
+                // This is the final component to add.
+                currentNode->subcomp[(currentNode->n) - 1] = componentAlloc(firstComponent, level);
+            } else {
+                // We are adding an intermediate component.  The trace level
+                // is not defined.  An undefined trace level inherits the
+                // trace level of it's parent.  However, we do not set that
+                // specifically here since that would inheritance to be a
+                // static, one-time, type of behavior.
+
+                currentNode->subcomp[(currentNode->n) - 1] = componentAlloc(firstComponent, PS_DEFAULT_TRACE_LEVEL);
+            }
+            currentNode = currentNode->subcomp[(currentNode->n) - 1];
+        }
+    }
+
+    return true;
+}
+
+/*****************************************************************************
+    psSetTraceLevel(): add the component named "comp" to the component tree,
+ if it is not already there, and set it's trace level to "level".
+ 
+    NOTE: We modified this so that the user may omit the leading "," in a
+    component name.  Since the code was already implemented assuming the "."
+    was required, rather than change all that code, in this function, I
+    simply add a leading "." to the component name if there is none.
+ 
+    Input:
+ comp
+ level
+    Output:
+ none
+    Returns:
+ zero
+*****************************************************************************/
+bool psTraceSetLevel(const char *comp,   // component of interest
+                     int level)  // desired trace level
+{
+    char *compName = NULL;
+
+    // If the root component tree does not exist, then initialize it.
+    if (cRoot == NULL) {
+        initTrace();
+    }
+
+    // If the component name has no leading dot, then supply it.
+    if (comp[0] != '.') {
+        compName = (char *) psAlloc(10 + strlen(comp));
+        strcpy(compName, ".");
+        compName = strcat(compName, comp);
+    } else {
+        compName = (char *) comp;
+    }
+
+    // Add the new component to the component tree.
+    if ( !componentAdd(compName, level) ) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psTraceSetLevel",
+                   PS_ERR_UNKNOWN,
+                   false,
+                   PS_ERRORTEXT_psTrace_FAILED_TO_ADD_COMPONENT,
+                   level,
+                   compName);
+        if (comp[0] != '.') {
+            psFree(compName);
+        }
+        return false;
+    }
+
+    if (comp[0] != '.') {
+        psFree(compName);
+    }
+
+    return true;
+}
+
+/*****************************************************************************
+    doGetTraceLevel()
+ This function recursively searches the root component tree for the
+ component named "name", which is supplied by a parameter.  If it
+ finds that component, it returns the level of that component.
+ Otherwise, it returns ???.
+ 
+    NOTE: We modified this so that the user may omit the leading "," in a
+    component name.  Since the code was already implemented assuming the "."
+    was required, rather than change all that code, in this function, I
+    simply add a leading "." to the component name if there is none.
+ 
+    Inputs:
+ name:
+    Outputs:
+ none
+    Returns:
+ The trace level of the "name" component.
+ *****************************************************************************/
+static int doGetTraceLevel(const char *aname)
+{
+    char name[strlen(aname) + 1];       // need a writeable copy: for strsep()
+    char *pname = name;
+    char *firstComponent = NULL;        // first component of name
+    p_psComponent* currentNode = cRoot;
+    int i = 0;
+    int defaultLevel = 0;
+
+    if (NULL == currentNode) {
+        return (PS_UNKNOWN_TRACE_LEVEL);
+    }
+
+    if (strcmp(".", aname) == 0) {
+        return (cRoot->level);
+    }
+
+    if (aname[0] != '.') {
+        return (PS_UNKNOWN_TRACE_LEVEL);
+    }
+
+    defaultLevel = cRoot->level;
+    strcpy(name, aname);
+    pname = &name[1];
+    while (pname != NULL) {
+        firstComponent = strsep(&pname, ".");
+        for (i = 0; i < currentNode->n; i++) {
+            if (NULL == currentNode->subcomp[i]) {
+                psLogMsg(PS_ERRORNAME_DOMAIN "p_psTraceReset", PS_LOG_WARN,
+                         PS_ERRORTEXT_psTrace_NULL_SUBCOMPONENT,
+                         i, currentNode->name);
+            }
+
+            if (strcmp(currentNode->subcomp[i]->name, firstComponent) == 0) {
+                currentNode = currentNode->subcomp[i];
+                // For level inheritance purpose, we save the level of this
+                // component if it is not DEFAULT.
+                if (currentNode->level != PS_DEFAULT_TRACE_LEVEL) {
+                    defaultLevel = currentNode->level;
+                }
+                // Determine if this is the last component:
+                if (pname == NULL) {
+                    if (currentNode->level != PS_DEFAULT_TRACE_LEVEL) {
+                        return (currentNode->level);
+                    } else {
+                        return(defaultLevel);
+                    }
+                }
+            }
+        }
+    }
+    return(defaultLevel);
+}
+
+/*****************************************************************************
+    psTraceLevelGet()
+ Return a trace level of "name" in the root component tree.  If the
+ exact string of components in "name" does not exist in the root
+ tree, we return the deepest level of the match.
+    Input:
+ name
+    Output:
+ none
+    Return:
+ The level of "name" in the root component tree.
+ *****************************************************************************/
+int psTraceGetLevel(const char *name)
+{
+    char *compName = NULL;
+    int traceLevel;
+
+    if (cRoot == NULL) {
+        return (PS_UNKNOWN_TRACE_LEVEL);
+    }
+
+    // If the component name has no leading dot, then supply it.
+    if (name[0] != '.') {
+        compName = (char *) psAlloc(10 + strlen(name));
+        strcpy(compName, ".");
+        compName = strcat(compName, name);
+        traceLevel = doGetTraceLevel(compName);
+        psFree(compName);
+    } else {
+        // Search the component root tree, determine the trace level.
+        traceLevel = doGetTraceLevel(name);
+    }
+    return(traceLevel);
+}
+
+/*****************************************************************************
+    doPrintTraceLevels()
+ This function recursively searches the component tree supplied by the
+ parameter "comp" and prints the name and level of each component.
+    Inputs:
+ comp: a node in the component tree.
+ level: the level of that node
+    Outputs:
+ none
+    Returns:
+ null
+ *****************************************************************************/
+static void doPrintTraceLevels(const p_psComponent* comp,
+                               int depth,
+                               int defLevel)
+{
+    int i = 0;
+
+    if (comp->name[0] == '\0') {
+        return;
+    } else {
+        if (comp->level == PS_DEFAULT_TRACE_LEVEL) {
+            if (traceFP == NULL) {
+                printf("%*s%-*s %d\n", depth, "", 20 - depth, comp->name,
+                       defLevel);
+            } else {
+                fprintf(traceFP,"%*s%-*s %d\n", depth, "", 20 - depth, comp->name,
+                        defLevel);
+            }
+        } else {
+            if (traceFP == NULL) {
+                printf("%*s%-*s %d\n", depth, "", 20 - depth, comp->name,
+                       comp->level);
+            } else {
+                fprintf(traceFP, "%*s%-*s %d\n", depth, "", 20 - depth, comp->name,
+                        comp->level);
+            }
+        }
+    }
+
+    for (i = 0; i < comp->n; i++) {
+        if (comp->level == PS_DEFAULT_TRACE_LEVEL) {
+            doPrintTraceLevels(comp->subcomp[i], depth + 1, defLevel);
+        } else {
+            doPrintTraceLevels(comp->subcomp[i], depth + 1, comp->level);
+        }
+    }
+}
+
+
+/*****************************************************************************
+psPrintTraceLevels(): Simply print all the trace levels in the trace level
+component tree.
+Inputs:
+ none
+Outputs:
+ none
+Returns:
+ null
+*****************************************************************************/
+void psTracePrintLevels(void)
+{
+    if (cRoot == NULL) {
+        return;
+    }
+
+    doPrintTraceLevels(cRoot, 0, PS_DEFAULT_TRACE_LEVEL);
+}
+
+/*****************************************************************************
+p_psTrace(): we display the trace message to standard output if the trace
+level of that message, supplied by the parameter "level" is higher than the
+trace level that is currently associated with the component named by the
+parameter "comp".
+Input:
+ comp
+ level
+ ...  a printf-style output string.
+Output:
+ none
+Return:
+ null
+ *****************************************************************************/
+void p_psTrace(const char *comp,        // component being traced
+               int level,       // desired trace level
+               ...)             // arguments
+{
+    char *fmt = NULL;
+    va_list ap;
+    int i = 0;
+
+    if (NULL == comp) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psTrace", PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psTrace_NULL_TRACETREE,
+                   __func__);
+        return;
+    }
+    // Only display this message if it's trace level is less than the level
+    // of it's associatedcomponent.
+    if (level <= psTraceGetLevel(comp)) {
+        va_start(ap, level);
+
+        // The following functions get the variable list of parameters with
+        // which this function was called, and print them to the standard
+        // output.
+        fmt = va_arg(ap, char *);
+
+        if (traceFP != NULL) {
+            // We indent each message one space for each level of the message.
+            for (i = 0; i < level; i++) {
+                fprintf(traceFP, " ");
+            }
+            vfprintf(traceFP, fmt, ap);
+        } else {
+            // We indent each message one space for each level of the message.
+            for (i = 0; i < level; i++) {
+                putchar(' ');
+            }
+            vprintf(fmt, ap);
+        }
+        va_end(ap);
+    }
+    // NOTE: should we free *fmt as well? Read the man page.
+}
+
+void psTraceSetDestination(FILE * fp)
+{
+    traceFP = fp;
+}
+
+#endif
Index: /branches/rel3/psLib/src/sys/psTrace.h
===================================================================
--- /branches/rel3/psLib/src/sys/psTrace.h	(revision 2163)
+++ /branches/rel3/psLib/src/sys/psTrace.h	(revision 2163)
@@ -0,0 +1,92 @@
+/** @file psTrace.h
+ *  \brief basic run-time trace facilities
+ *  \ingroup LogTrace
+ *
+ *  This file will hold the prototypes for defining procedures to insert
+ *  trace messages into the code.
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.23 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-20 22:03:35 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_TRACE_H)
+#define PS_TRACE_H 1
+
+#define PS_UNKNOWN_TRACE_LEVEL -9999   // we don't know this name's level
+#define PS_DEFAULT_TRACE_LEVEL -1
+
+/** \addtogroup LogTrace
+ *  \{
+ */
+
+/** Functions **************************************************************/
+
+//#define PS_NO_TRACE 1   ///< to turn off all tracing
+
+#if defined(PS_NO_TRACE)
+#        define psTrace(facil, level, ...) (void)0
+/* do nothing */
+#        define p_psTrace(facil, level, ...)  (void)0
+/* do nothing */
+#        define psTraceSetLevel(facil,level) 0
+#        define psTraceGetLevel(facil) 0
+#        define psTraceReset() (void)0     /* do nothing */
+#        define psTraceFree() (void)0      /* do nothing */
+#        define psTracePrintLevels() (void)0
+/* do nothing */
+#        define psTraceSetDestination(fp) (void)0
+/* do nothing */
+#    else
+
+    /** Basic structure for the component tree.  A component is a string of the
+        form aaa.bbb.ccc, and may itself contain further subcomponents.  The
+        Component structure doesn't in fact contain it's full name, but only the
+        last part. */
+    typedef struct p_psComponent
+    {
+        const char *name;           // last part of name of component
+        int level;                  // trace level for this component
+        int n;                      // number of subcomponents
+        struct p_psComponent* *subcomp;     // next level of subcomponents
+    }
+p_psComponent;
+
+#ifndef DOXYGEN
+/// Send a trace message
+void p_psTrace(const char *facil,       ///< facilty of interest
+               int myLevel,     ///< desired trace level
+               ...)             ///< trace message arguments
+;
+#endif
+
+/// Set trace level
+bool psTraceSetLevel(const char *facil,     ///< facilty of interest
+                     int level)     ///< desired trace level
+;
+
+/// Get the trace level
+int psTraceGetLevel(const char *facil)     ///< facilty of interest
+;
+
+/// Set all trace levels to zero (do not free nodes in the component tree).
+void psTraceReset();
+
+/// Free all nodes in the component tree.
+void psTraceFree();
+
+/// print trace levels
+void psTracePrintLevels(void);
+
+/// Set the destination of future trace messages.
+void psTraceSetDestination(FILE * fp);
+
+/* \} */// End of SystemGroup Functions
+
+#define psTrace(facil, level, ...) p_psTrace(facil, level, __VA_ARGS__)
+#endif
+
+#endif
Index: /branches/rel3/psLib/src/sys/psType.h
===================================================================
--- /branches/rel3/psLib/src/sys/psType.h	(revision 2163)
+++ /branches/rel3/psLib/src/sys/psType.h	(revision 2163)
@@ -0,0 +1,215 @@
+
+/** @file  psType.h
+*
+*  @brief Contains support for basic types
+*
+*  This file defines common datatypes used throughout psLib.
+*
+*  @ingroup DataContainer
+*
+*  @author Robert DeSonia, MHPCC
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.22 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-06 21:40:13 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#ifndef PS_TYPE_H
+#define PS_TYPE_H
+
+#include <complex.h>
+#include <stdint.h>
+#include <float.h>
+
+/// @addtogroup DataContainer
+/// @{
+
+/******************************************************************************/
+
+/*  TYPE DEFINITIONS                                                          */
+
+/******************************************************************************/
+
+/** Basic data types used by the containers.
+ *
+ * The basic types of the primitives used by psLib are defined within this enum. This enum is in turn used by
+ * the psType struct.
+ *
+ */
+
+typedef uint8_t psU8;                  ///< 8-bit unsigned int
+typedef uint16_t psU16;                ///< 16-bit unsigned int
+typedef uint32_t psU32;                ///< 32-bit unsigned int
+typedef uint64_t psU64;                ///< 64-bit unsigned int
+typedef int8_t psS8;                   ///< 8-bit signed int
+typedef int16_t psS16;                 ///< 16-bit signed int
+typedef int32_t psS32;                 ///< 32-bit signed int
+typedef int64_t psS64;                 ///< 64-bit signed int
+typedef float psF32;                   ///< 32-bit floating point
+typedef double psF64;                  ///< 64-bit floating point
+typedef float _Complex psC32;          ///< complex with 32-bit floating point Real and Imagary numbers
+typedef double _Complex psC64;         ///< complex with 64-bit floating point Real and Imagary numbers
+typedef void *psPTR;                   ///< void pointer
+
+typedef enum {
+    PS_TYPE_S8 = 0x0101,               ///< Character.
+    PS_TYPE_S16 = 0x0102,              ///< Short integer.
+    PS_TYPE_S32 = 0x0104,              ///< Integer.
+    PS_TYPE_S64 = 0x0108,              ///< Long integer.
+    PS_TYPE_U8 = 0x0301,               ///< Unsigned character.
+    PS_TYPE_U16 = 0x0302,              ///< Unsigned short integer.
+    PS_TYPE_U32 = 0x0304,              ///< Unsigned integer.
+    PS_TYPE_U64 = 0x0308,              ///< Unsigned long integer.
+    PS_TYPE_F32 = 0x0404,              ///< Single-precision Floating point.
+    PS_TYPE_F64 = 0x0408,              ///< Double-precision floating point.
+    PS_TYPE_C32 = 0x0808,              ///< Complex numbers consisting of single-precision floating point.
+    PS_TYPE_C64 = 0x0810,              ///< Complex numbers consisting of double-precision floating point.
+    PS_TYPE_PTR = 0x0000               ///< Something else that's not supported for arithmetic.
+} psElemType;
+
+#define PS_TYPE_MASK PS_TYPE_U8        /**< the psElemType to use for mask image */
+#define PS_TYPE_MASK_DATA U8           /**< the data member to use for mask image */
+#define PS_TYPE_MASK_NAME "psU8"       /**< the data type for mask as a string */
+
+typedef psU8 psMaskType;               ///< the C datatype for a mask image
+
+
+#define PS_MIN_S8        INT8_MIN      /**< minimum valid psS8 value */
+#define PS_MIN_S16       INT16_MIN     /**< minimum valid psS16 value */
+#define PS_MIN_S32       INT32_MIN     /**< minimum valid psS32 value */
+#define PS_MIN_S64       INT64_MIN     /**< minimum valid psS64 value */
+#define PS_MIN_U8        0             /**< minimum valid psU8 value */
+#define PS_MIN_U16       0             /**< minimum valid psU16 value */
+#define PS_MIN_U32       0             /**< minimum valid psU32 value */
+#define PS_MIN_U64       0             /**< minimum valid psU64 value */
+#define PS_MIN_F32       -FLT_MAX      /**< minimum valid psF32 value */
+#define PS_MIN_F64       -DBL_MAX      /**< minimum valid psF64 value */
+#define PS_MIN_C32       -FLT_MAX      /**< minimum valid real or imaginary psC32 value */
+#define PS_MIN_C64       -DBL_MAX      /**< minimum valid real or imaginary psC32 value */
+
+#define PS_MAX_S8        INT8_MAX      /**< maximum valid psS8 value */
+#define PS_MAX_S16       INT16_MAX     /**< maximum valid psS16 value */
+#define PS_MAX_S32       INT32_MAX     /**< maximum valid psS32 value */
+#define PS_MAX_S64       INT64_MAX     /**< maximum valid psS64 value */
+#define PS_MAX_U8        UINT8_MAX     /**< maximum valid psU8 value */
+#define PS_MAX_U16       UINT16_MAX    /**< maximum valid psU16 value */
+#define PS_MAX_U32       UINT32_MAX    /**< maximum valid psU32 value */
+#define PS_MAX_U64       UINT64_MAX    /**< maximum valid psU64 value */
+#define PS_MAX_F32       FLT_MAX       /**< maximum valid psF32 value */
+#define PS_MAX_F64       DBL_MAX       /**< maximum valid psF64 value */
+#define PS_MAX_C32       FLT_MAX       /**< maximum valid real or imaginary psC32 value */
+#define PS_MAX_C64       DBL_MAX       /**< maximum valid real or imaginary psC32 value */
+
+#define PS_TYPE_S8_NAME  "psS8"
+#define PS_TYPE_S16_NAME "psS16"
+#define PS_TYPE_S32_NAME "psS32"
+#define PS_TYPE_S64_NAME "psS64"
+#define PS_TYPE_U8_NAME  "psU8"
+#define PS_TYPE_U16_NAME "psU16"
+#define PS_TYPE_U32_NAME "psU32"
+#define PS_TYPE_U64_NAME "psU64"
+#define PS_TYPE_F32_NAME "psF32"
+#define PS_TYPE_F64_NAME "psF64"
+#define PS_TYPE_C32_NAME "psC32"
+#define PS_TYPE_C64_NAME "psC64"
+#define PS_TYPE_PTR_NAME "psPTR"
+
+#define PS_TYPE_NAME(value,type) \
+switch(type) { \
+case PS_TYPE_S8: \
+    value = PS_TYPE_S8_NAME; \
+    break; \
+case PS_TYPE_S16: \
+    value = PS_TYPE_S16_NAME; \
+    break; \
+case PS_TYPE_S32: \
+    value = PS_TYPE_S32_NAME; \
+    break; \
+case PS_TYPE_S64: \
+    value = PS_TYPE_S64_NAME; \
+    break; \
+case PS_TYPE_U8: \
+    value = PS_TYPE_U8_NAME; \
+    break; \
+case PS_TYPE_U16: \
+    value = PS_TYPE_U16_NAME; \
+    break; \
+case PS_TYPE_U32: \
+    value = PS_TYPE_U32_NAME; \
+    break; \
+case PS_TYPE_U64: \
+    value = PS_TYPE_U64_NAME; \
+    break; \
+case PS_TYPE_F32: \
+    value = PS_TYPE_F32_NAME; \
+    break; \
+case PS_TYPE_F64: \
+    value = PS_TYPE_F64_NAME; \
+    break; \
+case PS_TYPE_C32: \
+    value = PS_TYPE_C32_NAME; \
+    break; \
+case PS_TYPE_C64: \
+    value = PS_TYPE_C64_NAME; \
+    break; \
+case PS_TYPE_PTR: \
+    value = PS_TYPE_PTR_NAME; \
+    break; \
+default: \
+    value = "unknown"; \
+};
+
+/// Macro to get the bad pixel reason code (stored as part of mask value)
+#define PS_BADPIXEL_BITMASK 0x0f
+#define PS_GET_BADPIXEL(maskValue) (maskValue & PS_BADPIXEL_BITMASK)
+
+#define PS_IS_BADPIXEL(maskValue) (PS_GET_BADPIXEL(maskValue) != 0)
+
+/// Macro to apply a bad pixel reason code to mask image
+#define PS_SET_BADPIXEL(maskValue, reasonCode) \
+{ \
+    maskValue = (psMaskType)((reasonCode & PS_BADPIXEL_BITMASK) | (maskValue & ~PS_BADPIXEL_BITMASK)); \
+}
+
+/// Macro to determine if the psElemType is an integer.
+#define PS_IS_PSELEMTYPE_INT(x) ((x & 0x100) == 0x100)
+/// Macro to determine if the psElemType is unsigned.
+#define PS_IS_PSELEMTYPE_UNSIGNED(x) ((x & 0x200) == 0x200)
+/// Macro to determine if the psElemType is a real (non-complex) floating-point type.
+#define PS_IS_PSELEMTYPE_REAL(x) ((x & 0x400) == 0x400)
+/// Macro to determine if the psElemType is complex number type.
+#define PS_IS_PSELEMTYPE_COMPLEX(x) ((x & 0x800) == 0x800)
+/// Macro to determine the storage size, in bytes, of the psElemType.
+#define PSELEMTYPE_SIZEOF(x) ( (x==PS_TYPE_PTR) ? sizeof(void*) :(x & 0xFF) )
+
+/** Dimensions of a data type.
+ *
+ * The dimensions of containers used by psLib are defined within this enum. This enum is used by the psType
+struct. *
+ */
+typedef enum {
+    PS_DIMEN_SCALAR,            ///< Scalar.
+    PS_DIMEN_VECTOR,            ///< Vector.
+    PS_DIMEN_TRANSV,            ///< Transposed vector.
+    PS_DIMEN_IMAGE,             ///< Image.
+    PS_DIMEN_OTHER              ///< Something else that's not supported for arithmetic.
+} psDimen;
+
+/** The type of a data type.
+ *
+ * All psLib complex types consist of primitive components. This struct provides the description of those
+ * primitives.
+ *
+ */
+typedef struct
+{
+    psElemType type;            ///< Primitive type.
+    psDimen dimen;              ///< Dimensionality.
+}
+psType;
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/sysUtils/.cvsignore
===================================================================
--- /branches/rel3/psLib/src/sysUtils/.cvsignore	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/.cvsignore	(revision 2163)
@@ -0,0 +1,2 @@
+*.i
+psErrorCodes.h
Index: /branches/rel3/psLib/src/sysUtils/Makefile
===================================================================
--- /branches/rel3/psLib/src/sysUtils/Makefile	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/Makefile	(revision 2163)
@@ -0,0 +1,95 @@
+###############################################################################
+##
+##  Makefile:   sysUtils
+##
+##  $Revision: 1.22 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-09-09 22:21:00 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+###############################################################################
+
+# Define variable prefix to the top level project - psLib
+# This is necessary for definition is Makefile.Globals uses prefix
+
+ifndef prefix
+    export prefix=$(shell cd ../..;pwd)
+endif
+
+# Define the two targets to be built
+
+TARGET_STATIC  = libpslib.a
+
+# Include the make global definitions for the project
+
+include ../Makefile.Globals
+
+# Set CFLAGS used by the implicit rule to compile .c
+
+CFLAGS := $(CFLAGS_RELOC) -I../collections -I../dataManip -I../sysUtils -I../include -I..
+
+# Define the source objects
+ 
+SRC_OBJS = psMemory.o    \
+           psError.o     \
+           psTrace.o     \
+           psLogMsg.o    \
+           psAbort.o     \
+           psString.o    \
+           psErrorCodes.o 
+
+OBJS = $(addprefix makedir/,$(SRC_OBJS))
+
+HEADERS = $(SRC_OBJS:.o=.h) psType.h
+
+# Define PHONY target "all" which will make all the necessary items
+
+all: $(TARGET_STATIC)
+
+psErrorCodes.h: ../psErrorCodes.dat
+	perl ../parseErrorCodes.pl --data=$? $@
+
+psErrorCodes.c: ../psErrorCodes.dat
+	perl ../parseErrorCodes.pl --data=$? $@
+
+psSysUtilsErrors.h: psSysUtilsErrors.dat
+	perl ../parseErrorCodes.pl --data=$? $@
+
+
+# Rule to make static library
+
+libpslib.a: $(OBJS)
+# The ar option -r is to add/replace object and -s is to create
+# a symbol table in the archive
+	$(AR) rcs ../$@ $(OBJS)
+
+# Define PHONY target "install" which will install necessary files
+
+install: $(TARGET_STATIC) 
+	install $(HEADERS) $(includedir)
+
+# Define PHONY target "distclean" which will cleanup the distribution
+
+distclean:	clean
+	$(RM) ../$(TARGET_STATIC)
+
+# Define PHONY target "clean" which will cleanup the development area
+
+clean:
+	@echo "    Deleting intermediate files for 'sysUtils'"
+	$(RM) $(OBJS) *.lint
+
+cleandep:
+	$(RM) $(OBJS:.o=.d)
+
+%.lint: %.c
+	splint +posixlib -exportlocal -realcompare $(INCLUDE_GLOBAL) $? > $@; cat $@
+
+makedir/%.o: %.c
+	$(CC) -c $(CFLAGS) -o $@ $<
+
+makedir/%.d: %.c
+	$(CC) -MM $(CFLAGS) $< > $@.tmp
+	sed 's|\($*\)\.o[ :]*|\1.o $@ : |g' $@.tmp > $@
+	$(RM) -f $@.tmp
+
+include $(OBJS:.o=.d)
Index: /branches/rel3/psLib/src/sysUtils/README
===================================================================
--- /branches/rel3/psLib/src/sysUtils/README	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/README	(revision 2163)
@@ -0,0 +1,2 @@
+This directory includes code related to the 'system utilities' section of the
+IfA supplied SDR.
Index: /branches/rel3/psLib/src/sysUtils/psAbort.c
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psAbort.c	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psAbort.c	(revision 2163)
@@ -0,0 +1,38 @@
+
+/** @file  psAbort.c
+ *
+ *  @brief Contains the definition for abort function
+ *
+ *  The abort logging and handling shall be performed by psAbort function.
+ *  This will allow for consistent handling of other software units
+ *  needing to abort from program execution.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *   
+ *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-07 19:05:07 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include "psAbort.h"
+#include "psLogMsg.h"
+
+void psAbort(const char *name, const char *fmt, ...)
+{
+    va_list argPtr;             // variable list arguement pointer
+
+    // Get the variable list parameters to pass to logging function
+    va_start(argPtr, fmt);
+
+    // Call logging function with PS_LOG_ABORT level
+    psLogMsgV(name, PS_LOG_ABORT, fmt, argPtr);
+
+    // Clean up stack after variable arguement has been used
+    va_end(argPtr);
+
+    // Call system abort function to terminate program execution
+    abort();
+}
Index: /branches/rel3/psLib/src/sysUtils/psAbort.h
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psAbort.h	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psAbort.h	(revision 2163)
@@ -0,0 +1,47 @@
+
+/** @file  psAbort.h
+ *
+ *  @brief Contains the declarations for the abort function
+ *
+ *  The abort logging and handling shall be performed by psAbort function.
+ *  This will allow for consistent handling of other software units
+ *  needing to abort from program execution.
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-10 01:55:34 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ABORT_H
+#define PS_ABORT_H
+
+// Doxygen grouping tags
+
+/** @addtogroup ErrorHandling
+ *  @{
+ */
+
+/** Reports an abort message to logging facility
+ *
+ *  This function will invoke the psLogMsg function with a level of 
+ *  PS_LOG_ABORT and pass the parameters name and fmt to generate a proper
+ *  log message.  After logging, this function will call system abort 
+ *  function to abnormally terminate the program.
+ *
+ *  @return  void No return value
+ *
+ */
+void psAbort(
+    const char *name,                  ///< Source of abort such as file or function detected
+    const char *fmt,                   ///< A printf style formatting statement defining msg
+    ...
+);
+
+/* @} */// Doxygen - End of SystemGroup Functions
+
+#endif
Index: /branches/rel3/psLib/src/sysUtils/psError.c
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psError.c	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psError.c	(revision 2163)
@@ -0,0 +1,199 @@
+/** @file  psError.c
+ *
+ *  @brief Contains the definitions for the error reporting functions
+ *
+ *  Error reporting functions shall be used to create log entries in the
+ *  event errors are detected.  The messages shall give enough information
+ *  to allow the user to know where the error has occurred and the type
+ *  of error detected.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *   
+ *  @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-27 20:38:02 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdarg.h>
+#include <pthread.h>
+#include <string.h>
+
+#include "psLogMsg.h"
+#include "psError.h"
+#include "psMemory.h"
+
+#define MAX_ERROR_STACK_SIZE 64
+static psErr* errorStack[MAX_ERROR_STACK_SIZE];
+static unsigned int errorStackSize = 0;
+pthread_mutex_t lockErrorStack = PTHREAD_MUTEX_INITIALIZER;
+
+static void pushErrorStack(psErr* err);
+
+static void pushErrorStack(psErr* err)
+{
+
+    pthread_mutex_lock(&lockErrorStack);
+
+    if (errorStackSize < MAX_ERROR_STACK_SIZE) {
+        errorStack[errorStackSize] = psMemIncrRefCounter(err);
+        errorStackSize++;
+        p_psMemSetPersistent(err,true);
+        p_psMemSetPersistent(err->msg,true);
+        p_psMemSetPersistent(err->name,true);
+    }
+
+    pthread_mutex_unlock(&lockErrorStack);
+}
+
+static void errFree(psErr* err)
+{
+    if (err != NULL) {
+        psFree(err->msg);
+        psFree(err->name);
+    }
+}
+
+psErr* psErrAlloc(const char* name, psErrorCode code, const char* msg)
+{
+    psErr* err = psAlloc(sizeof(psErr));
+    err->msg = strcpy(psAlloc(strlen(msg) + 1), msg);
+    err->name = strcpy(psAlloc(strlen(name) + 1), name);
+    err->code = code;
+
+    p_psMemSetDeallocator(err,(psFreeFcn)errFree);
+
+    return err;
+}
+
+void psError(const char *name, const char *fmt, ...)
+{
+    va_list argPtr;             // variable list arguement pointer
+
+    // Get the variable list parameters to pass to logging function
+    va_start(argPtr, fmt);
+
+    // Call logging function with PS_LOG_ERROR level
+    psLogMsgV(name, PS_LOG_ERROR, fmt, argPtr);
+
+    // Clean up stack after variable argument has been used
+    va_end(argPtr);
+}
+
+void psErrorClear()
+{
+    pthread_mutex_lock(&lockErrorStack);
+    for (int lcv=0;lcv<errorStackSize;lcv++) {
+        p_psMemSetPersistent(errorStack[lcv]->msg,false);
+        p_psMemSetPersistent(errorStack[lcv]->name,false);
+        p_psMemSetPersistent(errorStack[lcv],false);
+        psFree(errorStack[lcv]);
+    }
+    errorStackSize = 0;
+    pthread_mutex_unlock(&lockErrorStack);
+}
+
+psErrorCode psErrorMsg(const char *name, psErrorCode code, bool new, const char* fmt, ...)
+{
+    char errMsg[1024];
+    psErr* err;
+    char* msgName;
+
+    // Check for null pointer and if found set to empty string;
+    if ( name == NULL ) {
+        msgName = "";
+    } else {
+        msgName = (char*)name;
+    }
+
+    va_list argPtr;             // variable list arguement pointer
+
+    if (new) {
+        psErrorClear();
+    }
+
+    // Get the variable list parameters to pass to logging function
+    va_start(argPtr, fmt);
+
+    vsnprintf(errMsg,1024,fmt,argPtr);
+    err = psErrAlloc(msgName,code,errMsg);
+    pushErrorStack(err);
+
+    // Call logging function with PS_LOG_ERROR level
+    psLogMsg(msgName, PS_LOG_ERROR, errMsg);
+
+    // Clean up stack after variable argument has been used
+    va_end(argPtr);
+
+    psFree(err);
+
+    return code;
+}
+
+psErr* psErrorGet(int which)
+{
+    psErr* result;
+
+    pthread_mutex_lock(&lockErrorStack);
+
+    // Check for negative reference and if found return PS_ERR_NONE
+    if (which < 0 ) {
+        result = psErrAlloc("", PS_ERR_NONE, "");
+    } else {
+
+        which = errorStackSize-1-which;     // the which input is from the end of errorStack
+        if (which < 0 || which >= errorStackSize) {
+            result = psErrAlloc("",PS_ERR_NONE,"");    // no error at the given location
+        } else {
+            result = psMemIncrRefCounter(errorStack[which]); // a new reference passed back
+        }
+    }
+
+    pthread_mutex_unlock(&lockErrorStack);
+
+    return result;
+}
+
+psErr* psErrorLast(void)
+{
+    return psErrorGet(0);
+}
+
+void psErrorStackPrint(FILE *fd, const char *fmt, ...)
+{
+    va_list argPtr;             // variable list arguement pointer
+
+    // Get the variable list parameters to pass to logging function
+    va_start(argPtr, fmt);
+
+    psErrorStackPrintV(fd,fmt,argPtr);
+
+    va_end(argPtr);
+}
+
+void psErrorStackPrintV(FILE *fd, const char *fmt, va_list va)
+{
+
+    pthread_mutex_lock(&lockErrorStack);
+
+    if (errorStackSize > 0) {
+        vfprintf(fd,fmt,va);
+
+        for (int lcv=0;lcv<errorStackSize;lcv++) {
+            if(errorStack[lcv]->code >= PS_ERR_BASE) {
+                fprintf(fd," -> %s: %s\n     %s\n",
+                        errorStack[lcv]->name,
+                        psErrorCodeString(errorStack[lcv]->code),
+                        errorStack[lcv]->msg);
+            } else {
+                fprintf(fd," -> %s: %s\n     %s\n",
+                        errorStack[lcv]->name,
+                        strerror(errorStack[lcv]->code),
+                        errorStack[lcv]->msg);
+            }
+        }
+    }
+
+    pthread_mutex_unlock(&lockErrorStack);
+}
+
Index: /branches/rel3/psLib/src/sysUtils/psError.h
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psError.h	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psError.h	(revision 2163)
@@ -0,0 +1,142 @@
+/** @file  psError.h
+ *
+ *  @brief Contains the declarations for the error reporting functions
+ *
+ *  Error reporting functions shall be used to create log entries in the
+ *  event errors are detected.  The messages shall give enough information
+ *  to allow the user to know where the error has occurred and the type
+ *  of error detected.
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.13 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-23 22:18:13 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ERROR_H
+#define PS_ERROR_H
+
+#include<stdio.h>
+#include<stdbool.h>
+#include<stdarg.h>
+
+#include "psErrorCodes.h"
+
+/** @addtogroup ErrorHandling
+ *  @{
+ */
+
+/** Error message object */
+typedef struct
+{
+    char* name;                        ///< category of code that caused the error
+    psErrorCode code;                  ///< class of error
+    char* msg;                         ///< the message associated with the error
+}
+psErr;
+
+/** Get a error from the error stack
+ *
+ *  Previous errors on the stack are returned by psErrorGet (a value of 0 
+ *  passed to psErrorGet is equivalent to a call to psErrorLast).
+ *
+ *  if no error is at the which position, a non-NULL psErr is returned with 
+ *  code PS_ERR_NONE.
+ *
+ *  @return    Error message object at 'which'
+ */
+psErr* psErrorGet(
+    int which                          ///< position in the error stack. 0 is last error on stack.
+);
+
+/** Get last error put on the error stack
+ *
+ *  The last error reported is available from psErrorLast; if no errors are 
+ *  current, a non-NULL psErr is returned with code PS_ERR_NONE.
+ *
+ *  @return psErr*     Reference to last error message on error stack
+ */
+psErr* psErrorLast(void);
+
+/** Clears the error stack.
+ *
+ *  The error stack may be completely cleared with psErrorClear.
+ *
+ */
+void psErrorClear(void);
+
+/** Prints error stack to specified open file descriptor
+ *
+ *  The entire error stack may be printed to an open file descriptor by 
+ *  calling psErrorStackPrint; if and only if there are current errors, the 
+ *  printf-style string fmt is first printed to the file descriptor fd. In 
+ *  this printout, error codes are replaced by their string equivalents.
+ *
+ */
+void psErrorStackPrint(
+    FILE* fd,                          ///< destination file descriptor
+    const char* fmt,                   ///< printf-style format of header line
+    ...                                ///< any parameters required in fmt
+);
+
+/** Prints error stack to specified open file descriptor
+ *
+ *  The entire error stack may be printed to an open file descriptor by 
+ *  calling psErrorStackPrintV; if and only if there are current errors, the 
+ *  vprintf-style string fmt is first printed to the file descriptor fd. In 
+ *  this printout, error codes are replaced by their string equivalents.
+ *
+ */
+void psErrorStackPrintV(
+    FILE* fd,                          ///< destination file descriptor
+    const char* fmt,                   ///< printf-style format of header line
+    va_list va                         ///< any parameters required in fmt
+);
+
+/** Reports an error message to the logging facility
+ *
+ *  This function will invoke the psLogMsg function with a level of
+ *  PS_LOG_ERROR and pass the parameters name and fmt to generate a proper
+ *  log message.
+ *
+ */
+void psError(
+    const char *name,                  ///< Source of error such as file or function detected
+    const char *fmt,                   ///< A printf style formatting statement defining msg
+    ...
+);
+
+/** Reports an error message to the logging facility
+ *
+ *  This function will invoke the psLogMsg function with a level of
+ *  PS_LOG_ERROR and pass the parameters name and fmt to generate a proper
+ *  log message.
+ *
+ */
+psErrorCode psErrorMsg(
+    const char *name,                  ///< Name of error in the form aaa.bbb.ccc
+    psErrorCode code,                  ///< Error class code
+    bool new,                          ///< true if error originates at this location
+    const char* fmt,                   ///< printf style formatting statement defining error message
+    ...
+);
+
+/** Create a new psErr struct
+ *
+ *  Creates a new psErr struct, making a copy of the parameters.
+ *
+ *  @return psErr*     new psErr object
+ */
+psErr* psErrAlloc(
+    const char* name,                  ///< Name of error in the form aaa.bbb.ccc
+    psErrorCode code,                  ///< Error class code
+    const char* msg                    ///< Error message
+);
+
+/* @} */// End of SysUtils Functions
+
+#endif
Index: /branches/rel3/psLib/src/sysUtils/psErrorCodes.c
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psErrorCodes.c	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psErrorCodes.c	(revision 2163)
@@ -0,0 +1,182 @@
+/** @file  psErrorCodes.c
+ *
+ *  @brief Contains the error codes for the error classes
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 21:14:58 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <string.h>
+
+#include "psError.h"
+#include "psErrorCodes.h"
+#include "psList.h"
+#include "psMemory.h"
+
+#include "psSysUtilsErrors.h"
+
+/* N.B., lines between '//~Start' and '//~End' are automatic generated from
+ * the template following the '//~Start'.  The template is used to generate
+ * the other lines by, for each error class in psErrorCodes.dat, the following
+ * substitutions are made:
+ *     $1  The error code name (first word in the psErrorCodes.dat lines)
+ *     $2  The error description (rest of the line in psErrorCodes.dat)
+ *     $n  The order of the source line in psErrorCodes.dat (comments excluded)
+ * 
+ * DO NOT EDIT THE LINES BETWEEN //~Start and //~End!  ANY CHANGES WILL BE OVERWRITTEN.
+ */
+
+static psErrorDescription staticErrorCodes[] = {
+            {PS_ERR_NONE,"not an error"},
+            {PS_ERR_BASE,"base error"},
+            //~Start    {PS_ERR_$1,"$2"},
+            {PS_ERR_UNKNOWN,"unknown error"},
+            {PS_ERR_IO,"I/O error"},
+            {PS_ERR_LOCATION_INVALID,"specified location is unknown"},
+            {PS_ERR_MEMORY_CORRUPTION,"memory corruption detected"},
+            {PS_ERR_MEMORY_DEREF_USAGE,"dereferenced memory still used"},
+            {PS_ERR_BAD_PARAMETER_VALUE,"parameter is out-of-range"},
+            {PS_ERR_BAD_PARAMETER_TYPE,"parameter is of unsupported type"},
+            {PS_ERR_BAD_PARAMETER_NULL,"parameter is null"},
+            {PS_ERR_BAD_PARAMETER_SIZE,"size of parameter's data is outside of acceptable range."},
+            {PS_ERR_UNEXPECTED_NULL,"unexpected NULL foun"},
+            //~End
+            {PS_ERR_N_ERR_CLASSES,"error classes end marker"}
+        };
+
+static psList* dynamicErrorCodes = NULL;
+static const psErrorDescription* getErrorDescription(psErrorCode code);
+
+
+static const psErrorDescription* getErrorDescription(psErrorCode code)
+{
+    // first, search the static error codes
+
+    int n = 0;
+    while(staticErrorCodes[n].code != PS_ERR_N_ERR_CLASSES &&
+            staticErrorCodes[n].code != code) {
+        n++;
+    }
+
+    if (staticErrorCodes[n].code == code) {
+        return &staticErrorCodes[n];
+    } else {
+        psErrorDescription* desc;
+        // make sure there is a list to search
+        if (dynamicErrorCodes == NULL) {
+            return NULL;
+        }
+
+        // search dynamic list of error descriptions before giving up.
+        desc = (psErrorDescription*)psListGet(dynamicErrorCodes,PS_LIST_HEAD);
+        while (desc != NULL) {
+            if (desc->code == code) {
+                return desc;
+            }
+            desc = (psErrorDescription*)psListGetNext(dynamicErrorCodes);
+        }
+    }
+    return NULL;
+}
+
+static void freeErrorDescription(psErrorDescription* err)
+{
+    psFree((void*)err->description);
+}
+
+psErrorDescription* psErrorDescriptionAlloc(psErrorCode code,
+        const char *description)
+{
+    psErrorDescription* err = psAlloc(sizeof(psErrorDescription));
+    err->code = code;
+    if (description == NULL) {
+        err->description = NULL;
+    } else {
+        err->description = psAlloc(sizeof(char)*strlen(description)+1);
+        strcpy((char*)err->description,description);
+    }
+
+    p_psMemSetDeallocator(err,(psFreeFcn)freeErrorDescription);
+    return err;
+}
+
+
+const char *psErrorCodeString(psErrorCode code)
+{
+    // Check input argument is non-negative
+    if ( code < 0 ) {
+        return NULL;
+    }
+
+    const psErrorDescription* desc = getErrorDescription(code);
+
+    if (desc == NULL) {
+        return NULL;
+    }
+
+    return desc->description;
+}
+
+void psErrorRegister(const psErrorDescription* errors,
+                     int nerror)
+{
+    if (nerror < 1) {
+        return;
+    }
+
+    if (errors == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psErrorRegister",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psErrorCode_NULL_ERRORDESCRIPTION);
+        return;
+    }
+
+    if (dynamicErrorCodes == NULL) {
+        dynamicErrorCodes = psListAlloc(NULL);
+        p_psMemSetPersistent(dynamicErrorCodes,true);
+    }
+
+    for (int i=0;i<nerror;i++) {
+        psErrorDescription* err = psErrorDescriptionAlloc(
+                                      errors[i].code, errors[i].description);
+        p_psMemSetPersistent(err,true);
+        p_psMemSetPersistent((void*)err->description,true);
+        if (! psListAdd(dynamicErrorCodes,
+                        PS_LIST_HEAD,
+                        err) ) {
+
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psErrorRegister",
+                       PS_ERR_UNKNOWN, false,
+                       PS_ERRORTEXT_psErrorCode_ERRORCODE_REGISTER_FAILED,
+                       i);
+        }
+        p_psMemSetPersistent(dynamicErrorCodes->head,true);
+        psFree(err);
+    }
+}
+
+bool p_psErrorUnregister(psErrorCode code)
+{
+    // Check input argument is non-negative
+    if ( code < 0 ) {
+        return false;
+    }
+
+    const psErrorDescription* desc = getErrorDescription(code);
+
+    if (desc == NULL) {
+        return false;
+    }
+
+    if (dynamicErrorCodes == NULL) {
+        return false;
+    }
+
+    return psListRemove(dynamicErrorCodes,PS_LIST_UNKNOWN,(void*)desc);
+}
Index: /branches/rel3/psLib/src/sysUtils/psErrorCodes.h
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psErrorCodes.h	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psErrorCodes.h	(revision 2163)
@@ -0,0 +1,108 @@
+/** @file  psErrorCodes.h
+ *
+ *  @brief Contains the error codes for the error classes
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 21:14:58 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ERROR_CODES_H
+#define PS_ERROR_CODES_H
+
+/* N.B., lines between '//~Start' and '//~End' are automatic generated from
+ * the template following the '//~Start'.  The template is used to generate
+ * the other lines by, for each error class in psErrorCodes.dat, the following
+ * substitutions are made:
+ *     $1  The error code name (first word in the psErrorCodes.dat lines)
+ *     $2  The error description (rest of the line in psErrorCodes.dat)
+ *     $n  The order of the source line in psErrorCodes.dat (comments excluded)
+ * 
+ * DO NOT EDIT THE LINES BETWEEN //~Start and //~End!  ANY CHANGES WILL BE OVERWRITTEN.
+ */
+
+/** @addtogroup ErrorHandling
+ *  @{
+ */
+
+/** enumeration of the static error code classes
+ */
+typedef enum {
+    PS_ERR_NONE = 0,                   ///< not an error
+    PS_ERR_BASE = 256,
+    /**< base error.  Any psErrorCode less than this should be taken to be
+     *   valid values of errno
+     */
+
+    //~Start     PS_ERR_$1,   ///< $2
+    PS_ERR_UNKNOWN,   ///< unknown error
+    PS_ERR_IO,   ///< I/O error
+    PS_ERR_LOCATION_INVALID,   ///< specified location is unknown
+    PS_ERR_MEMORY_CORRUPTION,   ///< memory corruption detected
+    PS_ERR_MEMORY_DEREF_USAGE,   ///< dereferenced memory still used
+    PS_ERR_BAD_PARAMETER_VALUE,   ///< parameter is out-of-range
+    PS_ERR_BAD_PARAMETER_TYPE,   ///< parameter is of unsupported type
+    PS_ERR_BAD_PARAMETER_NULL,   ///< parameter is null
+    PS_ERR_BAD_PARAMETER_SIZE,   ///< size of parameter's data is outside of acceptable range.
+    PS_ERR_UNEXPECTED_NULL,   ///< unexpected NULL foun
+    //~End
+    PS_ERR_N_ERR_CLASSES               ///< end marker - should not be used as a true error
+} psErrorCode;
+
+/** An error code with description
+ */
+typedef struct
+{
+    psErrorCode code;                  ///< An error code
+    const char *description;           ///< the associated description
+}
+psErrorDescription;
+
+/** Allocates a new psErrorDescription
+ *
+ *  @return psErrorDescription*        new psErrorDescription struct.
+ */
+psErrorDescription* psErrorDescriptionAlloc(
+    psErrorCode code,                  ///< An error code
+    const char *description            ///< the associated description
+);
+
+/** Retrieves the description of an error code.
+ *
+ *  The routine psErrorCodeString returns the string associated with an error 
+ *  code.
+ *
+ *  @return const char*     the description associated with the given code.
+ */
+const char *psErrorCodeString(
+    psErrorCode code                   ///< the associated error code
+);
+
+/** Register an error code
+ *
+ *  Any project needed to use psLib must define the necessary error codes and
+ *  associated message strings.  This function registers an array of error 
+ *  codes with the error handling subsystem.
+ *
+ */
+void psErrorRegister(
+    const psErrorDescription* errors,  ///< Array of error codes to register
+    int nerror                         ///< number of errors in input array
+);
+
+/** Clears error codes registered via psErrorRegister.
+ *
+ *  @return bool    TRUE if given errorcode was removed, otherwise FALSE.
+ */
+bool p_psErrorUnregister(
+    psErrorCode code                   ///< the error code to find and remove
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/sysUtils/psLogMsg.c
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psLogMsg.c	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psLogMsg.c	(revision 2163)
@@ -0,0 +1,392 @@
+/** @file  psLogMsg.c
+ *  @brief Procedures for logging messages.
+ *  \ingroup LogTrace
+ *
+ *  This file will hold the prototypes for defining procedure which set
+ *  message log levels, messahe log formats, message log destinations, and
+ *  for generating the messages themselves.
+ *  @ingroup LogTrace
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.33 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-14 20:01:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/*****************************************************************************
+NOTES: currently, the prototype code has the following global variables:
+    static int p_psGlobalLogDest;
+    static int p_psGlobalLogLevel;
+    static int p_psLogTime;
+    static int p_psLogHost;
+    static int p_psLogLevel;
+    static int p_psLogName;
+    static int p_psLogMsg;
+ *****************************************************************************/
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <time.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include "psLogMsg.h"
+#include "psError.h"
+#include "psTrace.h"
+
+#include "psSysUtilsErrors.h"
+
+#define MIN_LOG_LEVEL 0
+#define MAX_LOG_LEVEL 9
+
+#define MAX_LOG_LINE_LENGTH 128
+
+
+static FILE *logDest = (FILE *) 1;      // flag to initialize to stderr before using.
+static int globalLogLevel = PS_LOG_INFO;        // log all messages at this or above
+static bool logTime = true;     // Flag to include time info
+static bool logHost = true;     // Flag to include host info
+static bool logLevel = true;    // Flag to include level info
+static bool logName = true;     // Flag to include name info
+static bool logMsg = true;      // Flag to include message info
+
+/*****************************************************************************
+psLogSetLevel(): Set the current log level and return old level.
+Input:
+ level (int): the new log level.
+Output:
+ none
+Return:
+ The old log level.
+ *****************************************************************************/
+int psLogSetLevel(int level)
+{
+    // Save old global log level for changing it.
+    int oldLevel = globalLogLevel;
+
+    if ((level < MIN_LOG_LEVEL) || (level > MAX_LOG_LEVEL)) {
+        psLogMsg("logmsg", PS_LOG_WARN, "Attempt to set invalid logMsg level: %d", level);
+        level = (level < MIN_LOG_LEVEL) ? MIN_LOG_LEVEL : MAX_LOG_LEVEL;
+    }
+    // Set new global log level
+    globalLogLevel = level;
+
+    // Return old global log level
+    return oldLevel;
+}
+
+/*****************************************************************************
+psLogSetDestination(): sets the destination where log messages will be
+sent to.
+ 
+Input:
+ dest (int): the new log destination
+Output:
+ None.
+Return:
+ An integer specifying the old log destination.
+ *****************************************************************************/
+bool psLogSetDestination(const char *dest)
+{
+    char protocol[5];
+    char location[257];
+
+    // if logDest has not been initialized, do so before using it
+    if (logDest == (FILE *) 1) {
+        logDest = stderr;
+    }
+
+    if (dest == NULL || strcmp(dest, "none") == 0) {
+        if (logDest != NULL && logDest != stderr && logDest != stdout) {
+            fclose(logDest);
+        }
+        logDest = NULL;
+        return true;
+    }
+
+    if (sscanf(dest, "%4s:%256s", protocol, location) < 2) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psLogSetDestination", true, PS_ERR_LOCATION_INVALID,
+                   PS_ERRORTEXT_psLogMsg_DESTINATION_MALFORMED,
+                   dest);
+        return false;
+    }
+
+    if (strcmp(protocol, "dest") == 0) {
+        if (strcmp(location, "stderr") == 0) {
+            if (logDest != NULL && logDest != stderr && logDest != stdout) {
+                fclose(logDest);
+            }
+            logDest = stderr;
+            return true;
+        }
+        if (strcmp(location, "stdout") == 0) {
+            if (logDest != NULL && logDest != stderr && logDest != stdout) {
+                fclose(logDest);
+            }
+            logDest = stdout;
+            return true;
+        }
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psLogSetDestination", true, PS_ERR_LOCATION_INVALID,
+                   PS_ERRORTEXT_psLogMsg_DEST_LOCATION_INVALID,
+                   location);
+        return 1;
+    } else if (strcmp(protocol, "file") == 0) {
+        FILE *file = fopen(location, "w");
+
+        if (file == NULL) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psLogSetDestination", true, PS_ERR_IO,
+                       PS_ERRORTEXT_psLogMsg_OPEN_FILE_FAILED,
+                       location);
+            return false;
+        }
+        if (logDest != NULL && logDest != stderr && logDest != stdout) {
+            fclose(logDest);
+        }
+        logDest = file;
+        return true;
+    }
+
+    psErrorMsg(PS_ERRORNAME_DOMAIN "psLogSetDestination", true, PS_ERR_LOCATION_INVALID,
+               PS_ERRORTEXT_psLogMsg_UNSUPPORTED_PROTOCOL,
+               protocol);
+    return false;
+}
+
+/*****************************************************************************
+psLogSetFormat(): Set the format of psLogMsg output.  More precisely,
+    provide a string consisting of the letters {H (host), L (level), M
+    (message), N (name), T (time)}.  The default is "HLMNT".  This string
+    determines whether or not they associated type of information will be
+    included in message logs.  It does not determine the order in which that
+    information will appear (that order is fixed).
+ 
+Input:
+    fmt: a string specifying the format.
+Output:
+    none.
+Return:
+    NULL.
+ *****************************************************************************/
+void psLogSetFormat(const char *fmt)
+{
+    // assume nothing desired unless specified
+    logHost = false;
+    logLevel = false;
+    logMsg = false;
+    logName = false;
+    logTime = false;
+
+    // if fmt is NULL, no logging is desired.
+    if (fmt == NULL) {
+        return;
+    }
+
+    if (strlen(fmt) == 0) {
+        fmt = "THLNM";
+    }
+    // Step through each character in the format string.  For each letter
+    // in that string, set/unset the appropriate logging.
+
+    for (const char *ptr = fmt; *ptr != '\0'; ptr++) {
+        switch (*ptr) {
+        case 'H':
+        case 'h':
+            logHost = true;
+            break;
+        case 'L':
+        case 'l':
+            logLevel = true;
+            break;
+        case 'M':
+        case 'm':
+            logMsg = true;
+            break;
+        case 'N':
+        case 'n':
+            logName = true;
+            break;
+        case 'T':
+        case 't':
+            logTime = true;
+            break;
+        default:
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psLogSetFormat", true, PS_ERR_BAD_PARAMETER_VALUE,
+                       PS_ERRORTEXT_psLogMsg_UNKNOWN_KEY, *ptr);
+            break;
+        }
+    }
+
+    if (!logMsg) {
+        psTrace("utils.logMsg", 1, "You must at least log error messages (You chose \"%s\")", fmt);
+    }
+}
+
+#if !defined(HOST_NAME_MAX)                // should be in limits.h
+#define HOST_NAME_MAX 256
+#endif
+
+/*****************************************************************************
+    psVLogMsg(): This routine sends the message, which is a printf style
+ string specified in the "..." argument, to the current message log
+ destination with the severity specified by the "level" argument.
+    Input:
+ name
+ level
+ fmt
+ ap
+    Output:
+ none
+    Return:
+ NULL.
+ *****************************************************************************/
+void psLogMsgV(const char *name, int level, const char *fmt, va_list ap)
+{
+    static int first = 1;       // Flag for calling gethostname()
+    static char hostname[HOST_NAME_MAX + 1];
+
+    // Buffer for hostname.
+    char clevel = 0;            // letter-name for level
+    char head[MAX_LOG_LINE_LENGTH + 2]; // the added two are for the ending | and \0
+    char *head_ptr = head;      // where we've got to in head
+    int maxLength = MAX_LOG_LINE_LENGTH;
+    time_t clock = time(NULL);  // The current time.
+    struct tm *utc = gmtime(&clock);    // The current gm time.
+
+    // if logDest has not been initialized, do so before using it
+    if (logDest == (FILE *) 1) {
+        logDest = stderr;
+    }
+    // If logging is off, or if the level is too high, return immediately.
+    if ((level > globalLogLevel) || (logDest == NULL)) {
+        return;
+    }
+    // If I have not been here yet, determine my hostname and save it.
+    if (first) {
+        first = 0;
+        gethostname(hostname, HOST_NAME_MAX);
+    }
+
+    switch (level) {
+    case PS_LOG_ABORT:
+        clevel = 'A';
+        break;
+
+    case PS_LOG_ERROR:
+        clevel = 'E';
+        break;
+
+    case PS_LOG_WARN:
+        clevel = 'W';
+        break;
+
+    case PS_LOG_INFO:
+        clevel = 'I';
+        break;
+
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+        clevel = level + '0';
+        break;
+
+    default:
+        psTrace("utils.logMsg", 2, "Invalid logMsg level: %d (%s)\n", level, fmt);
+        level = (level < 0) ? 0 : 9;
+        clevel = level + '0';
+        break;
+    }
+
+    // Create the various log fields...
+    if (logTime) {
+        maxLength -= snprintf(head_ptr, maxLength, "%4d:%02d:%02d %02d:%02d:%02dZ",
+                              utc->tm_year + 1900, utc->tm_mon + 1, utc->tm_mday,
+                              utc->tm_hour, utc->tm_min, utc->tm_sec) - 1;
+        head_ptr += strlen(head_ptr);
+    }
+    // Hostname should be 20 characters.
+    if (logHost) {
+        if (head_ptr > head) {
+            *head_ptr++ = '|';
+        }
+        maxLength -= snprintf(head_ptr, maxLength, "%-20s", hostname);
+        head_ptr += strlen(head_ptr);
+    }
+    if (logLevel) {
+        if (head_ptr > head) {
+            *head_ptr++ = '|';
+        }
+        maxLength -= snprintf(head_ptr, maxLength, "%c", clevel);
+        head_ptr += strlen(head_ptr);
+    }
+    if (logName) {
+        if (head_ptr > head) {
+            *head_ptr++ = '|';
+        }
+        maxLength -= snprintf(head_ptr, maxLength, "%s", name);
+
+        head_ptr += strlen(head_ptr);
+    }
+
+    if (head_ptr > head) {
+        *head_ptr++ = '\n';
+    } else if (!logMsg) {                  // no output desired
+        return;
+    }
+    *head_ptr = '\0';
+
+    fputs(head, logDest);
+    if (logMsg) {
+        char msg[1024];
+        char* msgPtr;
+        vsnprintf(msg,1024, fmt, ap);  // create message
+
+        // detect multiple lines in message and indent each line by 4 spaces.
+        char* line = strtok_r(msg,"\n",&msgPtr);
+        while (line != NULL) {
+            fprintf(logDest,"    %s\n",line);
+            line = strtok_r(NULL,"\n",&msgPtr);
+        }
+    } else {
+        fputc('\n', logDest);
+    }
+}
+
+/*****************************************************************************
+    psLogMsg(): This routine sends the message, which is a printf style
+ string specified in the "..." argument, to the current message log
+ destination with the severity specified by the "level" argument.
+    Input:
+ name: Indicates the source of this log message.
+ level: The severity of this log message.
+ fmt: The printf-stype formatted string, followed by the arguments
+  to that string.
+ ... The arguments to the above printf-style string.
+    Output:
+ none
+    Return:
+ NULL
+ *****************************************************************************/
+void psLogMsg(const char *name, int level, const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    psLogMsgV(name, level, fmt, ap);
+    va_end(ap);
+}
+void psWarning(const char* name, const char* fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    psLogMsgV(name, PS_LOG_WARN, fmt, ap);
+    va_end(ap);
+}
Index: /branches/rel3/psLib/src/sysUtils/psLogMsg.h
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psLogMsg.h	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psLogMsg.h	(revision 2163)
@@ -0,0 +1,116 @@
+/** @file  psLogMsg.h
+ *  @brief Procedures for logging messages.
+ *  \ingroup LogTrace
+ *
+ *  This file will hold the prototypes for defining procedure which set
+ *  message log levels, messahe log formats, message log destinations, and
+ *  for generating the messages themselves.
+ *  @ingroup LogTrace
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-14 20:01:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_LOG_MSG_H)
+#define PS_LOG_MSG_H
+#include <stdarg.h>
+#include <stdbool.h>
+
+/** @addtogroup LogTrace
+ *  @{
+ */
+
+/** This procedure sets the destination for future log messages.  Currently
+ *  the destination is specified by an integer which can have the following
+ *  pre-defined values: PS_LOG_NONE, PS_LOG_TO_STDOUT, and PS_LOG_TO_STDERR.
+ *  In future versions, this procedure will take a character string as an
+ *  argument which can specify more general log destinations.
+ *
+ *  @return int     true if set successfully, otherwise false.
+ */
+bool psLogSetDestination(
+    const char *dest                   ///< Specifies where to send messages.
+);
+
+/** This procedure sets the message level for future log messages.  Subsequent
+ *  log messages, with a log level of "mylevel", will only be logged if
+ *  "mylevel" is less than the current log level set by this procedure.
+ *  Ie. higher values set by this procedure will cause more log messages to
+ *  be displayed.
+ *
+ *  @return int    old logging level
+ */
+int psLogSetLevel(
+    int level                          ///< Specifies the system log level
+);
+
+/** This procedure sets the log format for future log messages.  The argument
+ *  must be a character string consistsing of the letters H (host), L
+ *  (level), M (message), N (name), and T (time).  The default is "THLNM".
+ *  Deleting a letter from the string will cause the associated information
+ *  to not be logged.
+ *
+ */
+void psLogSetFormat(
+    const char *fmt                    ///< Specifies the system log format
+);
+
+/** This procedure logs a message to the destination set by a prior
+ *  call to psLogSetDestination(), if myLevel is less than the level
+ *  specified by a prior call to psLogSetLevel().  The message is specified
+ *  with a printf-stype string an arguments.
+ *
+ */
+void psLogMsg(
+    const char *name,                  ///< name of the log source
+    int myLevel,                       ///< severity level of this log message
+    const char *fmt,                   ///< printf-style format command
+    ...
+);
+
+/** This procedure is functionally equivalent to psLogMsg(), except that
+ *  it takes a va_list as the message parameter, not a printf-style string.
+ *
+ */
+void psLogMsgV(
+    const char *name,                  ///< name of the log source
+    int myLevel,                       ///< severity level of this log message
+    const char *fmt,                   ///< printf-style format command
+    va_list ap                         ///< varargs argument list
+);
+
+///< Status codes for log messages
+enum {
+    PS_LOG_ABORT = 0,                  ///< log message is a critical error, perform an abort after printing
+    PS_LOG_ERROR,                      ///< log message is an error, but don't abort
+    PS_LOG_WARN,                       ///< log message is a warning
+    PS_LOG_INFO                        ///< log message is informational only
+};
+
+///< Destinations for log messages
+enum {
+    PS_LOG_NONE,                       ///< turn off logging
+    PS_LOG_TO_STDERR,                  ///< log to system's stderr
+    PS_LOG_TO_STDOUT                   ///< log to system's stdout
+};
+
+/** Logs a warning message.
+ *
+ *  This procedure logs a message to the destination set by a prior
+ *  call to psLogSetDestination(), This is equivalent to calling
+ *  psLogMsg with a level of PS_LOG_WARN.
+ *
+ */
+void psWarning(
+    const char* name,
+    const char* fmt,
+    ...
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/sysUtils/psMemory.c
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psMemory.c	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psMemory.c	(revision 2163)
@@ -0,0 +1,695 @@
+/** @file  psMemory.c
+*
+*  @brief Contains the definitions for the memory management system
+*
+*  psMemory.h has additional information and documentation of the routines found in this file.
+*
+*  @author Robert DeSonia, MHPCC
+*  @author Robert Lupton, Princeton University
+*
+*  @version $Revision: 1.41 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-09-21 22:30:19 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#define PS_ALLOW_MALLOC                    // we're allowed to call malloc()
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psLogMsg.h"
+
+#include "psSysUtilsErrors.h"
+
+#define P_PS_MEMMAGIC (void *)0xdeadbeef   // Magic number in psMemBlock header
+
+#define P_PS_LARGE_BLOCK_SIZE 65536        // size where under, we try to recycle
+
+static int checkMemBlock(const psMemBlock* m, const char *funcName);
+static psMemBlock* lastMemBlockAllocated = NULL;
+static pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t memIdMutex = PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_mutex_t recycleMemBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
+
+static int recycleBins = 13;
+static int recycleBinSize[14] = {
+                                    8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, P_PS_LARGE_BLOCK_SIZE
+                                };
+
+// N.B. recycleBinSize should be terminated by P_PS_LARGE_BLOCK_SIZE (simplifies search loops)
+static psMemBlock* recycleMemBlockList[13] = {
+            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+        };
+
+#ifdef PS_MEM_DEBUG
+static psMemBlock* deadBlockList;       // a place to put dead memBlocks in debug mode.
+#endif
+
+/**
+ * Unique ID for allocated blocks
+ */
+static psMemoryId memid = 0;
+
+/**
+ *  Default memExhausted callback.
+ */
+static void *memExhaustedCallbackDefault(size_t size)
+{
+    void *ptr = NULL;
+
+    pthread_mutex_lock(&recycleMemBlockListMutex);
+    int level = recycleBins - 1;
+
+    while (level >= 0 && ptr == NULL) {
+        while (recycleMemBlockList[level] != NULL && ptr == NULL) {
+            psMemBlock* old = recycleMemBlockList[level];
+
+            recycleMemBlockList[level] = recycleMemBlockList[level]->nextBlock;
+            free(old);
+            ptr = malloc(size);
+        }
+        level--;
+    }
+    pthread_mutex_unlock(&recycleMemBlockListMutex);
+
+    return ptr;
+}
+
+static psMemExhaustedCallback memExhaustedCallback = memExhaustedCallbackDefault;
+
+psMemExhaustedCallback psMemExhaustedCallbackSet(psMemExhaustedCallback func)
+{
+    psMemExhaustedCallback old = memExhaustedCallback;
+
+    if (func != NULL) {
+        memExhaustedCallback = func;
+    } else {
+        memExhaustedCallback = memExhaustedCallbackDefault;
+    }
+
+    return old;
+}
+
+static void memProblemCallbackDefault(const psMemBlock* ptr, const char *file, int lineno)
+{
+    if (ptr->refCounter < 1) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "memProblemCallbackDefault", false, PS_ERR_MEMORY_CORRUPTION,
+                   PS_ERRORTEXT_psMemory_MULTIPLE_FREE,
+                   ptr->id, ptr->file, ptr->lineno, file, lineno);
+    }
+
+    if (lineno > 0) {
+        psAbort(__func__, "Detected a problem in the memory system at %s:%d", file, lineno);
+    }
+}
+static psMemProblemCallback memProblemCallback = memProblemCallbackDefault;
+
+psMemProblemCallback psMemProblemCallbackSet(psMemProblemCallback func)
+{
+    psMemProblemCallback old = memProblemCallback;
+
+    if (func != NULL) {
+        memProblemCallback = func;
+    } else {
+        memProblemCallback = memProblemCallbackDefault;
+    }
+
+    return old;
+}
+
+/*
+ * And now the I-want-to-be-informed callbacks
+ *
+ * Call the callbacks when these IDs are allocated/freed
+ */
+psMemoryId p_psMemAllocateID = 0;       // notify user this block is allocated
+psMemoryId p_psMemFreeID = 0;   // notify user this block is freed
+
+psMemoryId psMemAllocateCallbackSetID(psMemoryId id)
+{
+    psMemoryId old = p_psMemAllocateID;
+
+    p_psMemAllocateID = id;
+
+    return old;
+}
+
+psMemoryId psMemFreeCallbackSetID(psMemoryId id)
+{
+    psMemoryId old = p_psMemFreeID;
+
+    p_psMemFreeID = id;
+
+    return old;
+}
+
+/*
+ * Default callback for both allocate and free. Note that the
+ * value of p_psMemAllocateID/p_psMemFreeID is incremented
+ * by the return value (so returning 0 means that the callback
+ * isn't resignalled)
+ */
+static psMemoryId memAllocateCallbackDefault(const psMemBlock* ptr)
+{
+    static psMemoryId incr = 0; // "p_psMemAllocateID += incr"
+
+    return incr;
+}
+
+static psMemoryId memFreeCallbackDefault(const psMemBlock* ptr)
+{
+    static psMemoryId incr = 0; // "p_psMemFreeID += incr"
+
+    return incr;
+}
+
+/*
+ * The default callbacks, and the routines to change them
+ */
+static psMemAllocateCallback memAllocateCallback = memAllocateCallbackDefault;
+static psMemFreeCallback memFreeCallback = memFreeCallbackDefault;
+
+psMemAllocateCallback psMemAllocateCallbackSet(psMemAllocateCallback func)
+{
+    psMemFreeCallback old = memAllocateCallback;
+
+    if (func != NULL) {
+        memAllocateCallback = func;
+    } else {
+        memAllocateCallback = memAllocateCallbackDefault;
+    }
+
+    return old;
+}
+
+psMemFreeCallback psMemFreeCallbackSet(psMemFreeCallback func)
+{
+    psMemFreeCallback old = memFreeCallback;
+
+    if (func != NULL) {
+        memFreeCallback = func;
+    } else {
+        memFreeCallback = memFreeCallbackDefault;
+    }
+
+    return old;
+}
+
+/*
+ * Return memory ID counter for next block to be allocated
+ */
+psMemoryId psMemGetId(void)
+{
+    psMemoryId id;
+
+    pthread_mutex_lock(&memIdMutex);
+    id = memid + 1;
+    pthread_mutex_unlock(&memIdMutex);
+
+    return id;
+}
+
+/*
+ * Routines to check the consistency of the allocated and/or free memory arena
+ *
+ * N.b. If the block wasn't allocated by psAlloc, it will appear corrupted
+ */
+
+static int checkMemBlock(const psMemBlock* m, const char *funcName)
+{
+    // n.b. since this is called by psMemCheckCorruption while the memblock list is mutex locked,
+    // we shouldn't call such things as p_psAlloc/p_psFree here.
+
+    if (m == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "checkMemBlock", true, PS_ERR_MEMORY_CORRUPTION,
+                   PS_ERRORTEXT_psMemory_NULL_BLOCK);
+        return 1;
+    }
+
+    if (m->refCounter == 0) {
+        // using an unreferenced block of memory, are you?
+        psErrorMsg(PS_ERRORNAME_DOMAIN "checkMemBlock", true, PS_ERR_MEMORY_CORRUPTION,
+                   PS_ERRORTEXT_psMemory_DEREF_BLOCK_USE,
+                   m->id);
+        return 1;
+    }
+
+    if (m->startblock != P_PS_MEMMAGIC || m->endblock != P_PS_MEMMAGIC) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "checkMemBlock", true, PS_ERR_MEMORY_CORRUPTION,
+                   PS_ERRORTEXT_psMemory_UNDERFLOW,
+                   m->id);
+        return 1;
+    }
+    if (*(void **)((int8_t *) (m + 1) + m->userMemorySize) != P_PS_MEMMAGIC) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "checkMemBlock", true, PS_ERR_MEMORY_CORRUPTION,
+                   PS_ERRORTEXT_psMemory_OVERFLOW,
+                   m->id);
+        return 1;
+    }
+
+    return 0;
+}
+
+int psMemCheckCorruption(bool abort_on_error)
+{
+    int nbad = 0;               // number of bad blocks
+    bool failure = false;
+
+    // get exclusive access to the memBlock list to avoid it changing on us while we use it.
+    //    pthread_mutex_lock(&memBlockListMutex);
+
+    for (psMemBlock* iter = lastMemBlockAllocated; iter != NULL; iter = iter->nextBlock) {
+        pthread_mutex_unlock(&memBlockListMutex);
+        failure = checkMemBlock(iter, __func__);
+        pthread_mutex_lock(&memBlockListMutex);
+        if ( failure ) {
+            nbad++;
+
+            memProblemCallback(iter, __func__, __LINE__);
+
+            if (abort_on_error) {
+                // release the lock on the memblock list
+                pthread_mutex_unlock(&memBlockListMutex);
+                psAbort(__func__, "Detected memory corruption");
+                return nbad;
+            }
+        }
+    }
+
+    // release the lock on the memblock list
+    pthread_mutex_unlock(&memBlockListMutex);
+    return nbad;
+}
+
+void *p_psAlloc(size_t size, const char *file, int lineno)
+{
+
+    psMemBlock* ptr = NULL;
+
+    // memory is of the size I want to bother recycling?
+    if (size < P_PS_LARGE_BLOCK_SIZE) {
+        // find the bin we need.
+        int level = 0;
+
+        while (size > recycleBinSize[level]) {
+            level++;
+        }
+        // Are we in one of the bins
+        if (level < recycleBins) {
+
+            size = recycleBinSize[level];  // round-up size to next sized bin.
+
+            pthread_mutex_lock(&recycleMemBlockListMutex);
+
+            if (recycleMemBlockList[level] != NULL) {
+                ptr = recycleMemBlockList[level];
+                recycleMemBlockList[level] = ptr->nextBlock;
+                if (recycleMemBlockList[level] != NULL) {
+                    recycleMemBlockList[level]->previousBlock = NULL;
+                }
+                size = ptr->userMemorySize;
+            }
+
+            pthread_mutex_unlock(&recycleMemBlockListMutex);
+        }
+    }
+
+    if (ptr == NULL) {
+        ptr = malloc(sizeof(psMemBlock) + size + sizeof(void *));
+
+        if (ptr == NULL) {
+            ptr = memExhaustedCallback(size);
+            if (ptr == NULL) {
+                psAbort(__func__, "Failed to allocate %u bytes at %s:%d", size, file, lineno);
+            }
+        }
+
+        ptr->startblock = P_PS_MEMMAGIC;
+        ptr->endblock = P_PS_MEMMAGIC;
+        ptr->userMemorySize = size;
+        pthread_mutex_init(&ptr->refCounterMutex, NULL);
+    }
+    // increment the memory id safely.
+    pthread_mutex_lock(&memBlockListMutex);
+    *(psMemoryId* ) & ptr->id = ++memid;
+    pthread_mutex_unlock(&memBlockListMutex);
+
+    ptr->file = file;
+    ptr->freeFcn = NULL;
+    ptr->persistent = false;
+    *(unsigned int *)&ptr->lineno = lineno;
+    *(void **)((int8_t *) (ptr + 1) + size) = P_PS_MEMMAGIC;
+    ptr->previousBlock = NULL;
+
+    ptr->refCounter = 1;                   // one user so far
+
+    // need exclusive access of the memory block list now...
+    pthread_mutex_lock(&memBlockListMutex);
+
+    // insert the new block to the front of the memBlock linked-list
+    ptr->nextBlock = lastMemBlockAllocated;
+    if (ptr->nextBlock != NULL) {
+        ptr->nextBlock->previousBlock = ptr;
+    }
+    lastMemBlockAllocated = ptr;
+
+    pthread_mutex_unlock(&memBlockListMutex);
+
+    // Did the user ask to be informed about this allocation?
+    if (ptr->id == p_psMemAllocateID) {
+        p_psMemAllocateID += memAllocateCallback(ptr);
+    }
+    // And return the user the memory that they allocated
+    return ptr + 1;                        // user memory
+}
+
+void *p_psRealloc(void *vptr, size_t size, const char *file, int lineno)
+{
+    if (vptr == NULL) {
+        return p_psAlloc(size, file, lineno);
+    } else {
+        psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+        bool isBlockLast = false;
+
+        if (checkMemBlock(ptr, __func__) != 0) {
+            memProblemCallback(ptr, file, lineno);
+            psAbort(file, "Realloc detected a memory corruption (id %ld @ %s:%d).",
+                    ptr->id, ptr->file, ptr->lineno);
+        }
+
+        pthread_mutex_lock(&memBlockListMutex);
+
+        isBlockLast = (ptr == lastMemBlockAllocated);
+
+        ptr = (psMemBlock* ) realloc(ptr, sizeof(psMemBlock) + size + sizeof(void *));
+
+        if (ptr == NULL) {
+            ptr = memExhaustedCallback(size);
+            if(ptr == NULL) {
+                psAbort(__func__, "Failed to reallocate %ld bytes at %s:%d", size, file, lineno);
+            }
+        }
+
+        ptr->userMemorySize = size;
+        *(void **)((int8_t *) (ptr + 1) + size) = P_PS_MEMMAGIC;
+
+        if (isBlockLast) {
+            lastMemBlockAllocated = ptr;
+        }
+        // the block location may have changed, so fix the linked list addresses.
+        if (ptr->nextBlock != NULL) {
+            ptr->nextBlock->previousBlock = ptr;
+        }
+        if (ptr->previousBlock != NULL) {
+            ptr->previousBlock->nextBlock = ptr;
+        }
+
+        pthread_mutex_unlock(&memBlockListMutex);
+
+        // Did the user ask to be informed about this allocation?
+        if (ptr->id == p_psMemAllocateID) {
+            p_psMemAllocateID += memAllocateCallback(ptr);
+        }
+
+        return ptr + 1;                    // usr memory
+    }
+}
+
+void p_psFree(void *vptr, const char *file, int lineno)
+{
+    if (vptr == NULL) {
+        return;
+    }
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+    if (ptr->refCounter < 1) {
+        psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psFree",PS_ERR_MEMORY_DEREF_USAGE,true,
+                   PS_ERRORTEXT_psMemory_MULTIPLE_FREE,
+                   ptr->id, ptr->file, ptr->lineno, file, lineno);
+
+        return;
+    }
+    (void)p_psMemDecrRefCounter(vptr, file, lineno);    // this handles the free, if required.
+}
+
+/*
+ * Check for memory leaks.
+ */
+int psMemCheckLeaks(psMemoryId id0, psMemBlock* ** arr, FILE * fd)
+{
+    int nleak = 0;
+    int j = 0;
+    psMemBlock* topBlock = lastMemBlockAllocated;
+
+    pthread_mutex_lock(&memBlockListMutex);
+
+    for (psMemBlock* iter = topBlock; iter != NULL; iter = iter->nextBlock) {
+        if ( (iter->refCounter > 0) &&
+                (! iter->persistent) &&
+                (iter->id >= id0)) {
+
+            nleak++;
+
+            if (fd != NULL) {
+                if (nleak == 1) {
+                    fprintf(fd, "   %20s:line ID\n", "file");
+                }
+
+                fprintf(fd, "   %20s:%-4d %ld\n", iter->file, iter->lineno, iter->id);
+            }
+        }
+    }
+
+    pthread_mutex_unlock(&memBlockListMutex);
+
+    if (nleak == 0 || arr == NULL) {
+        return nleak;
+    }
+
+    *arr = p_psAlloc(nleak * sizeof(psMemBlock), __FILE__, __LINE__);
+    pthread_mutex_lock(&memBlockListMutex);
+
+    for (psMemBlock* iter = topBlock; iter != NULL; iter = iter->nextBlock) {
+        if ( (iter->refCounter > 0) &&
+                (! iter->persistent) &&
+                (iter->id >= id0)) {
+
+            (*arr)[j++] = iter;
+            if (j == nleak) {              // found them all
+                break;
+            }
+        }
+    }
+
+    pthread_mutex_unlock(&memBlockListMutex);
+
+    return nleak;
+}
+
+/*
+ * Reference counting APIs
+ */
+// return refCounter
+psReferenceCount psMemGetRefCounter(void *vptr)
+{
+    psMemBlock* ptr;
+    unsigned int refCount;
+
+    if (vptr == NULL) {
+        return 0;
+    }
+
+    ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    pthread_mutex_lock(&ptr->refCounterMutex);
+    refCount = ptr->refCounter;
+    pthread_mutex_unlock(&ptr->refCounterMutex);
+
+    return refCount;
+}
+
+// increment and return refCounter
+void *p_psMemIncrRefCounter(void *vptr, const char *file, int lineno)
+{
+    psMemBlock* ptr;
+
+    if (vptr == NULL) {
+        return vptr;
+    }
+
+    ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__)) {
+        memProblemCallback(ptr, file, lineno);
+    }
+
+    pthread_mutex_lock(&ptr->refCounterMutex);
+    ptr->refCounter++;
+    pthread_mutex_unlock(&ptr->refCounterMutex);
+
+    return vptr;
+}
+
+// decrement and return refCounter
+void *p_psMemDecrRefCounter(void *vptr, const char *file, int lineno)
+{
+    if (vptr == NULL) {
+        return NULL;
+    }
+
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, file, lineno);
+        return NULL;
+    }
+
+    pthread_mutex_lock(&ptr->refCounterMutex);
+
+    if (ptr->refCounter > 1) {
+        ptr->refCounter--;                 // multiple references, just decrement the count.
+        pthread_mutex_unlock(&ptr->refCounterMutex);
+
+    } else {
+        pthread_mutex_unlock(&ptr->refCounterMutex);
+
+        // Did the user ask to be informed about this deallocation?
+        if (ptr->id == p_psMemFreeID) {
+            p_psMemFreeID += memFreeCallback(ptr);
+        }
+
+        if (ptr->freeFcn != NULL) {
+            ptr->freeFcn(vptr);
+        }
+
+        pthread_mutex_lock(&memBlockListMutex);
+
+        // cut the memBlock out of the memBlock list
+        if (ptr->nextBlock != NULL) {
+            ptr->nextBlock->previousBlock = ptr->previousBlock;
+        }
+        if (ptr->previousBlock != NULL) {
+            ptr->previousBlock->nextBlock = ptr->nextBlock;
+        }
+        if (lastMemBlockAllocated == ptr) {
+            lastMemBlockAllocated = ptr->nextBlock;
+        }
+
+        pthread_mutex_unlock(&memBlockListMutex);
+
+        // do we need to recycle?
+        if (ptr->userMemorySize < P_PS_LARGE_BLOCK_SIZE) {
+
+            int level = 1;
+
+            while (ptr->userMemorySize >= recycleBinSize[level]) {
+                level++;
+            }
+            level--;
+
+            ptr->refCounter = 0;
+            ptr->previousBlock = NULL;
+
+            pthread_mutex_lock(&recycleMemBlockListMutex);
+            ptr->nextBlock = recycleMemBlockList[level];
+            if (recycleMemBlockList[level] != NULL) {
+                recycleMemBlockList[level]->previousBlock = ptr;
+            }
+            recycleMemBlockList[level] = ptr;
+            pthread_mutex_unlock(&recycleMemBlockListMutex);
+
+        } else {
+            // memory is larger than I want to recycle.
+            #ifdef PS_MEM_DEBUG
+            (void)p_psRealloc(vptr, 0, file, lineno);
+            ptr->previousBlock = NULL;
+            ptr->nextBlock = deadBlockList;
+            if (deadBlockList != NULL) {
+                deadBlockList->previous = ptr;
+            }
+            deadBlockList = ptr;
+            #else
+
+            pthread_mutex_destroy(&ptr->refCounterMutex);
+            free(ptr);
+            #endif
+
+        }
+
+        vptr = NULL;                       // since we freed it, make sure we return NULL.
+    }
+
+    return vptr;
+}
+
+void p_psMemSetDeallocator(void *vptr, psFreeFcn freeFcn)
+{
+    if (vptr == NULL) {
+        return;
+    }
+
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    ptr->freeFcn = freeFcn;
+
+}
+psFreeFcn p_psMemGetDeallocator(void *vptr)
+{
+    if (vptr == NULL) {
+        return NULL;
+    }
+
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    return ptr->freeFcn;
+}
+
+bool p_psMemGetPersistent(void *vptr)
+{
+    if (vptr == NULL) {
+        return NULL;
+    }
+
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    return ptr->persistent;
+}
+
+void p_psMemSetPersistent(void *vptr,bool value)
+{
+    if (vptr == NULL) {
+        return;
+    }
+
+    psMemBlock* ptr = ((psMemBlock* ) vptr) - 1;
+
+    if (checkMemBlock(ptr, __func__) != 0) {
+        memProblemCallback(ptr, __func__, __LINE__);
+    }
+
+    ptr->persistent = value;
+}
Index: /branches/rel3/psLib/src/sysUtils/psMemory.h
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psMemory.h	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psMemory.h	(revision 2163)
@@ -0,0 +1,445 @@
+/** @file  psMemory.h
+ *
+ *  @brief Contains the definitions for the memory management system
+ *
+ *  This is the generic memory management system put inbetween the user's high level code and the OS-level
+ *  memory allocation routines.  This system adds such features as callback routines for memory error events,
+ *  tracing capabilities, and reference counting.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Robert Lupton, Princeton University
+ *
+ *  @ingroup MemoryManagement
+ *
+ *  @version $Revision: 1.30 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-14 23:48:25 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#if !defined(PS_MEMORY_H)
+#define PS_MEMORY_H
+
+#include <stdio.h>                     // needed for FILE
+#include <stdbool.h>
+#include <pthread.h>                   // we need a mutex to make this stuff thread safe.
+
+/** @addtogroup MemoryManagement
+ *  @{
+ */
+
+/**
+ *  @addtogroup memCallback Memory Callbacks
+ *
+ *  Routines dealing with the creating and setting of memory management callback functions.
+ */
+
+/**
+ *  @addtogroup memTracing Memory Tracing
+ *
+ *  Routines dealing with memory tracing and corruption checking.
+ */
+
+/**
+ *  @addtogroup memRefCount Reference Count
+ *
+ *  Routines dealing with the reference counting of allocated buffers.
+ */
+
+/// typedef for memory identification numbers.  Guaranteed to be some variety of integer.
+typedef unsigned long psMemoryId;
+
+/// typedef for a memory block's reference count. Guaranteed to be some variety of integer.
+typedef unsigned long psReferenceCount;
+
+/// typedef for deallocator.
+typedef void (*psFreeFcn) (void *ptr);
+
+/** Book-keeping data for storage allocator.
+ *  N.b. sizeof(psMemBlock) must be chosen such that if ptr is a pointer
+ *  returned by malloc, then ((char *)ptr + sizeof(psMemBlock)) is properly
+ *  aligned for all storage types.
+ */
+typedef struct psMemBlock
+{
+    const void *startblock;            ///< initialised to p_psMEMMAGIC
+    struct psMemBlock* previousBlock;  ///< previous block in allocation list
+    struct psMemBlock* nextBlock;      ///< next block allocation list
+    psFreeFcn freeFcn;                 ///< deallocator.  If NULL, use generic deallocation.
+    size_t userMemorySize;             ///< the size of the user-portion of the memory block
+    const psMemoryId id;               ///< a unique ID for this allocation
+    const char *file;                  ///< set from __FILE__ in e.g. p_psAlloc
+    const int lineno;                  ///< set from __LINE__ in e.g. p_psAlloc
+    pthread_mutex_t refCounterMutex;   ///< mutex to ensure exclusive access to reference counter
+    psReferenceCount refCounter;       ///< how many times pointer is referenced
+    bool persistent;                   ///< marks if this non-user persistent data like error stack, etc.
+    const void *endblock;              ///< initialised to p_psMEMMAGIC
+}
+psMemBlock;
+
+/** prototype of a basic callback used by memory functions
+ *
+ *  @see psMemAllocateCallbackSet
+ *  @ingroup memCallback
+ */
+typedef psMemoryId(*psMemAllocateCallback) (
+    const psMemBlock* ptr              ///< the psMemBlock just allocated
+);
+
+/** prototype of memory free callback used by memory functions
+ *
+ *  @see psMemFreeCallbackSet
+ *  @ingroup memCallback
+ */
+typedef psMemoryId(*psMemFreeCallback) (
+    const psMemBlock* ptr              ///< the psMemBlock being freed
+);
+
+/** prototype of a callback used in error conditions
+ *
+ *  This callback should not try to call psAlloc or psFree.
+ *
+ *  @see psMemProblemCallbackSet
+ *  @ingroup memCallback
+ */
+typedef void (*psMemProblemCallback) (
+    const psMemBlock* ptr,             ///< the pointer to the problematic memory block.
+    const char *file,                  ///< the file in which the problem originated
+    int lineno                         ///< the line number in which the problem originated
+);
+
+/** prototype of a callback function used when memory runs out
+ *
+ *  @return void* pointer to requested buffer of the size size_t, or NULL if memory could not
+ *          be found.
+ *
+ *  @see psMemExhaustedCallbackSet
+ *  @ingroup memCallback
+ */
+typedef void *(*psMemExhaustedCallback) (
+    size_t size                        ///< the size of buffer required
+);
+
+/** Memory allocation.  This operates much like malloc(), but is guaranteed to return a non-NULL value.
+ *
+ *  @return void* pointer to the allocated buffer. This will not be NULL.
+ *  @see psFree 
+ */
+#ifdef DOXYGEN
+void *psAlloc(size_t size       ///< Size required
+             );
+#else
+
+void *p_psAlloc(size_t size,    ///< Size required
+                const char *file,       ///< File of call
+                int lineno      ///< Line number of call
+               );
+
+/// Memory allocation. psAlloc sends file and line number to p_psAlloc.
+#define psAlloc(size) p_psAlloc(size, __FILE__, __LINE__)
+#endif
+
+/** Set the deallocator routine
+ *
+ *  A deallocator routine can optionally be assigned to a memory block to 
+ *  ensure that associated memory blocks also get freed, e.g., memory buffers
+ *  referenced within a struct.
+ *
+ */
+void p_psMemSetDeallocator(
+    void *ptr,                         ///< the memory block to operate on
+    psFreeFcn freeFcn                  ///< the function to be executed at deallocation
+);
+
+/** Get the deallocator routine
+ *
+ *  This function returns the deallocator for a memory block.  A deallocator 
+ *  routine can optionally be assigned to a memory block to ensure that 
+ *  associated memory blocks also get freed, e.g., memory buffers referenced 
+ *  within a struct.  
+ *
+ *  @return psFreeFcn    the routine to be called at deallocation.
+ */
+psFreeFcn p_psMemGetDeallocator(
+    void *ptr                          ///< the memory block
+);
+
+/** Set the memory as persistent so that it is ignored when detecting memory leaks.
+ *
+ *  Used to mark a memory block as persistent data within the library, 
+ *  i.e., non user-level data used to hold psLib's state or cache data.  Such
+ *  examples of this class of memory is psTrace's trace-levels and dynamic
+ *  error codes.
+ *
+ *  Memory marked as persistent is excluded from memory leak checks.
+ *
+ */
+void p_psMemSetPersistent(
+    void *ptr,                         ///< the memory block to operate on
+    bool value                         ///< true if memory is persistent, otherwise false
+);
+
+/** Get the memory's persistent flag.
+ *
+ *  Checks if a memory block has been marked as persistent by 
+ *  p_psMemSetPresistent.
+ *
+ *  Memory marked as persistent is excluded from memory leak checks.
+ *
+ *  @return bool    true if memory is marked persistent, otherwise false.
+ */
+bool p_psMemGetPersistent(
+    void *ptr                          ///< the memory block to check.
+);
+
+
+/** Memory re-allocation.  This operates much like realloc(), but is guaranteed to return a non-NULL value.
+ *
+ *  @return void* pointer to resized buffer. This will not be NULL.
+ *  @see psAlloc, psFree
+ */
+#ifdef DOXYGEN
+void *psRealloc(
+    void *ptr                          ///< Pointer to re-allocate
+    size_t size,                       ///< Size required
+);
+#else
+
+void *p_psRealloc(
+    void *ptr,                         ///< Pointer to re-allocate
+    size_t size,                       ///< Size required
+    const char *file,                  ///< File of call
+    int lineno                         ///< Line number of call
+);
+
+/// Memory re-allocation.  psRealloc sends file and line number to p_psRealloc.
+#define psRealloc(ptr, size) p_psRealloc(ptr, size, __FILE__, __LINE__)
+
+#endif
+
+/** Free memory.  This operates much like free().
+ *
+ *  @see psAlloc, psRealloc
+ */
+#ifdef DOXYGEN
+void psFree(
+    void *ptr,                         ///< Pointer to free, if NULL, function returns immediately.
+);
+#else
+
+void p_psFree(
+    void *ptr,                        ///< Pointer to free
+    const char *file,                 ///< File of call
+    int lineno                        ///< Line number of call
+);
+
+/// Free memory.  psFree sends file and line number to p_psFree.
+#define psFree(size) p_psFree(size, __FILE__, __LINE__)
+
+#endif
+
+/** Check for memory leaks.  This scans for allocated memory buffers not freed with an ID not less than id0.
+ *  This is used to check for memory leaks by:
+ *      -# before a block of code to be checked, store the current ID count via psGetMemId
+ *      -# after the block of code to be checked, call this function using the ID stored above.  If all
+ *         memory in the block that was allocated has been freed, this call should output nothing and
+ *         return 0.
+ *
+ *  If memory leaks are found, the Memory Problem callback will be called as well.
+ *
+ *  return int  number of memory blocks found as 'leaks', i.e., the number of currently allocated memory
+ *              blocks above id0 that have not been freed.
+ *  @see psAlloc, psFree, psgetMemId, psMemProblemCallbackSet
+ *  @ingroup memTracing
+ */
+int psMemCheckLeaks(
+    psMemoryId id0,                    ///< don't list blocks with id < id0
+    psMemBlock* ** arr,                ///< pointer to array of pointers to leaked blocks, or NULL
+    FILE * fd                          ///< print list of leaks to fd (or NULL)
+);
+
+/** Check for memory corruption.  Scans all currently allocated memory buffers and checks for corruptions,
+ *  i.e., invalid markers that signify a buffer under/overflow.
+ *
+ *  @ingroup memTracing
+ */
+int psMemCheckCorruption(
+    bool abort_on_error                ///< Abort on detecting corruption?
+);
+
+/** Return reference counter
+ *
+ *  @ingroup memRefCount
+ */
+psReferenceCount psMemGetRefCounter(
+    void *vptr                         ///< Pointer to get refCounter for
+);
+
+/** Increment reference counter and return the pointer
+ *
+ *  @ingroup memRefCount
+ */
+#ifdef DOXYGEN
+void *psMemIncrRefCounter(
+    void *vptr                         ///< Pointer to increment refCounter, and return
+);
+#else
+
+void *p_psMemIncrRefCounter(
+    void *vptr,                        ///< Pointer to increment refCounter, and return
+    const char *file,                  ///< File of call
+    int lineno                         ///< Line number of call
+);
+
+#define psMemIncrRefCounter(vptr) p_psMemIncrRefCounter(vptr, __FILE__, __LINE__)
+#endif
+
+/** Decrement reference counter and return the pointer
+ *
+ *  @ingroup memRefCount
+ *
+ *  @return void*    the pointer deremented in refCount, or NULL if pointer is 
+ *                   fully dereferenced.
+ */
+#ifdef DOXYGEN
+void* psMemDecrRefCounter(
+    void* vptr                         ///< Pointer to decrement refCounter, and return
+);
+#else
+
+void *p_psMemDecrRefCounter(
+    void *vptr,                        ///< Pointer to decrement refCounter, and return
+    const char *file,                  ///< File of call
+    int lineno                         ///< Line number of call
+);
+
+#define psMemDecrRefCounter(vptr) p_psMemDecrRefCounter(vptr, __FILE__, __LINE__)
+#endif
+
+/** Set callback for problems.
+ *
+ *  At various occasions, the memory manager can check the state of the memory 
+ *  stack. If any of these checks discover that the memory stack is corrupted,
+ *  the psMemProblemCallback is called.
+ 
+ *  @ingroup memCallback
+ *
+ *  @return psMemProblemCallback       old psMemProblemCallback function
+ */
+psMemProblemCallback psMemProblemCallbackSet(
+    psMemProblemCallback func          ///< Function to run at memory problem detection
+);
+
+/** Set callback for out-of-memory.
+ *
+ *  If not enough memory is available to satisfy a request by psAlloc or 
+ *  psRealloc, these functions attempt to find an alternative solution by 
+ *  calling the psMemExhaustedCallback, a function which may be set by the 
+ *  programmer in appropriate circumstances, rather than immediately fail. 
+ *  The typical use of such a feature may be when a program needs a large 
+ *  chunk of memory to do an operation, but the exact size is not critical. 
+ *  This feature gives the programmer the opportunity to make a smaller 
+ *  request and try again, limiting the size of the operating buffer.
+ *
+ *  @ingroup memCallback
+ *
+ *  @return psMemExhaustedCallback     old psMemExhaustedCallback function
+ */
+psMemExhaustedCallback psMemExhaustedCallbackSet(
+    psMemExhaustedCallback func        ///< Function to run at memory exhaustion
+);
+
+/** Set call back for when a particular memory block is allocated
+ *
+ *  A private variable, p_psMemAllocateID, can be used to trace the allocation 
+ *  and freeing of specific memory blocks. If p_psMemAllocateID is set and a 
+ *  memory block with that ID is allocated, psMemAllocateCallback is called 
+ *  just before memory is returned to the calling function.
+ *
+ *  @ingroup memCallback
+ *
+ *  @return psMemAllocateCallback      old psMemAllocateCallback function
+ */
+psMemAllocateCallback psMemAllocateCallbackSet(
+    psMemAllocateCallback func       ///< Function to run at memory allocation of specific mem block
+);
+
+/** Set call back for when a particular memory block is freed
+ *
+ *  A private variable, p_psMemFreeID, can be used to trace the freeing of 
+ *  specific memory blocks. If p_psMemFreeID is set and the memory block with 
+ *  the ID is about to be freed, the psMemFreeCallback callback is called just
+ *  before the memory block is freed.
+ *
+ *  @ingroup memCallback
+ *
+ *  @return psMemFreeCallback          old psMemFreeCallback function
+ */
+psMemFreeCallback psMemFreeCallbackSet(
+    psMemFreeCallback func             ///< Function to run at memory free of specific mem block
+);
+
+/** get next memory ID
+ *
+ *  @ingroup memCallback
+ *
+ *  @return psMemoryId                 the next memory ID to be used
+ */
+psMemoryId psMemGetId(void);
+
+/** set p_psMemAllocateID to specific id
+ *
+ *  A private variable, p_psMemAllocateID, can be used to trace the allocation 
+ *  and freeing of specific memory blocks. If p_psMemAllocateID is set and a 
+ *  memory block with that ID is allocated, psMemAllocateCallback is called 
+ *  just before memory is returned to the calling function.
+ *
+ *  @ingroup memCallback
+ *
+ *  @return psMemoryId       
+ *
+ *  @see psMemAllocateCallbackSet    
+ */
+psMemoryId psMemAllocateCallbackSetID(
+    psMemoryId id                      ///< ID to set
+);
+
+/** set p_psMemFreeID to id
+ *
+ *  A private variable, p_psMemFreeID, can be used to trace the freeing of 
+ *  specific memory blocks. If p_psMemFreeID is set and the memory block with 
+ *  the ID is about to be freed, the psMemFreeCallback callback is called just
+ *  before the memory block is freed.
+ *
+ *  @ingroup memCallback
+ *
+ *  @return psMemoryId                 the old p_psMemFreeID
+ *
+ *  @see psMemFreeCallbackSet
+ */
+psMemoryId psMemFreeCallbackSetID(
+    psMemoryId id                      ///< ID to set
+);
+
+//@} End of Memory Management Functions
+
+#ifndef DOXYGEN
+
+/*
+ * Ensure that any program using malloc/realloc/free will fail to compile
+ */
+#ifndef PS_ALLOW_MALLOC
+#ifdef __GNUC__
+#pragma GCC poison malloc realloc calloc free
+#else
+#define malloc(S)       _Pragma("error Use of malloc is not allowed.  Use psAlloc instead.")
+#define realloc(P,S)    _Pragma("error Use of realloc is not allowed.  Use psRealloc instead.")
+#define calloc(S)       _Pragma("error Use of calloc is not allowed.  Use psAlloc instead.")
+#define free(P)         _Pragma("error Use of free is not allowed.  Use psFree instead.")
+#endif
+#endif
+
+#endif
+// doxygen skip
+
+#endif // end of header file
Index: /branches/rel3/psLib/src/sysUtils/psString.c
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psString.c	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psString.c	(revision 2163)
@@ -0,0 +1,56 @@
+
+/** @file  psString.c
+ *
+ *  @brief Contains the definition of string utility functions
+ *
+ *  String utility functions defined shall provide basic string copying
+ *  capabilities while using the preferred memory management utilities.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-06 01:05:41 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "psString.h"
+#include "psMemory.h"
+#include "psError.h"
+
+#include "psSysUtilsErrors.h"
+
+char *psStringCopy(const char *str)
+{
+    // Allocate memory using psAlloc function
+    // Copy input string to memory just allocated
+    // Return the copy
+    return strcpy(psAlloc(strlen(str) + 1), str);
+}
+
+char *psStringNCopy(const char *str, int nChar)
+{
+    char *returnValue = NULL;
+
+    // Check the number of characters to copy is non-negative
+    if (nChar < 0) {
+        // Log error message and return NULL
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psStringNCopy", PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psString_NCHAR_NEGATIVE,
+                   nChar);
+        return NULL;
+    }
+    // Allocate memory using psAlloc function - nChar bytes
+    // Copy input string to memory allocated up to nChar characters
+    // Return the copy
+    returnValue = strncpy(psAlloc((size_t) nChar + 1), str, (size_t) nChar);
+
+    // Ensure the last byte is NULL character
+    if (nChar > 0) {
+        returnValue[nChar] = '\0';
+    }
+    // Return the string pointer
+    return returnValue;
+}
Index: /branches/rel3/psLib/src/sysUtils/psString.h
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psString.h	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psString.h	(revision 2163)
@@ -0,0 +1,70 @@
+/** @file  psString.h
+ *
+ *  @brief Contains the declarations of string utility functions
+ *
+ *  @ingroup SysUtils
+ *
+ *  String utility functions defined shall provide basic string copying
+ *  capabilities.
+ *
+ *  @author Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-10 01:55:34 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_STRING_H
+#define PS_STRING_H
+
+
+/** This macro will convert the argument to a quoted string */
+#define PS_STRING(S)  #S
+
+// Doxygen group tags
+
+/** @addtogroup SysUtils
+ *  @{
+ */
+
+/** Copies the input string
+ *
+ *  This function shall allocate memory to the length of the input string
+ *  plus one and copy the input string to the newly allocated memory.
+ *
+ *  @return char*      Copy of input string
+ *
+ */
+char *psStringCopy(
+    const char *str
+    /**< Input string of characters to copy */
+);
+
+/** Copies the input string up to the specified number of characters
+ *
+ *  This function shall allocate memory to the length specified by nChar
+ *  plus one and copy the input string to the newly allocated memory.
+ *  This function will only copy nChar bytes from the input to new string,
+ *  so if the input string is larger than nChar characters the copied
+ *  string will be a substring of the input string.  If the input string
+ *  is smaller than nChar bytes then the remaining bytes allocated will
+ *  be set to NULL.
+ *
+ *  @return  char* Copy of input string
+ *
+ */
+
+/*@null@*/
+
+char *psStringNCopy(
+    const char *str,
+    /**< Input string of characters to copy */
+
+    int nChar
+    /**< Number of bytes to allocate for string copy */
+);
+
+/* @} */// Doxygen - End of SystemGroup Functions
+
+#endif
Index: /branches/rel3/psLib/src/sysUtils/psSysUtilsErrors.dat
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psSysUtilsErrors.dat	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psSysUtilsErrors.dat	(revision 2163)
@@ -0,0 +1,44 @@
+#
+#  This file is used to generate psSysUtilsErrors.h content
+#
+#  Format is:
+#  ERRORNAME(one word)    ERROR_TEXT
+#
+#  N.b. The ERRORNAME is exposed in the code as PS_ERR_ERRORNAME, e.g.,
+#  if ERRORNAME=psMemory_NULL_BLOCK, then use PS_ERR_psMemory_NULL_BLOCK in
+#  the code.
+#
+####################################################################
+#
+# Error Messages from psLogMsg.c:
+#
+psLogMsg_DESTINATION_MALFORMED         The specified destination, %s, is malformed.
+psLogMsg_DEST_LOCATION_INVALID         The location, %s, for protocol 'dest' is invalid.
+psLogMsg_OPEN_FILE_FAILED              Could not open file '%s' for output.
+psLogMsg_UNSUPPORTED_PROTOCOL          Do not know how to handle the protocol '%s'.
+psLogMsg_UNKNOWN_KEY                   Unknown logging keyword %c.
+#
+# Error Messages from psMemory.c:
+#
+psMemory_NULL_BLOCK                    NULL memory block found.
+psMemory_DEREF_BLOCK_USE               Memory block %ld was freed but still being used.
+psMemory_UNDERFLOW                     Memory block %ld is corrupted; buffer underflow detected.
+psMemory_OVERFLOW                      Memory block %ld is corrupted; buffer overflow detected.
+psMemory_MULTIPLE_FREE                 Block %ld, allocated at %s:%d, freed multiple times at %s:%d.
+#
+# Error Messages from psString.c:
+#
+psString_NCHAR_NEGATIVE                Can not copy a negative number of characters (%d).
+#
+# Error Messages from psTrace.c:
+#
+psTrace_NULL_SUBCOMPONENT              Sub-component %d of node %s in trace tree is NULL.
+psTrace_NULL_TRACETREE                 Function %s called on a NULL trace level tree.
+psTrace_ADD_NULL_COMPONENT             Failed to add null component to trace tree.
+psTrace_MALFORMED_COMPONENT_NAME       Failed to add '%s' to the root component tree; component must start with '.'.
+psTrace_FAILED_TO_ADD_COMPONENT        Failed to set trace level (%d) to '%s'.
+#
+# Error Messages from psErrorCodes.c
+#
+psErrorCode_NULL_ERRORDESCRIPTION      Specified psErrorDescription pointer can not be NULL.
+psErrorCode_ERRORCODE_REGISTER_FAILED  Failed to add input psErrorDescription at array index %d.
Index: /branches/rel3/psLib/src/sysUtils/psSysUtilsErrors.h
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psSysUtilsErrors.h	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psSysUtilsErrors.h	(revision 2163)
@@ -0,0 +1,52 @@
+/** @file  psSysUtilsErrors.h
+ *
+ *  @brief Contains the error text for the system utility functions
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-27 20:38:02 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_SYSUTILS_ERRORS_H
+#define PS_SYSUTILS_ERRORS_H
+
+/* N.B., lines between '//~Start' and '//~End' are automatic generated from
+ * the template following the '//~Start'.  The template is used to generate
+ * the other lines by, for each error text in psSysUtilsErrors.dat, the following
+ * substitutions are made:
+ *     $1  The error text macro name (first word in the psSysUtilsErrors.dat lines)
+ *     $2  The error text (rest of the line in psSysUtilsErrors.dat)
+ *     $n  The order of the source line in psSysUtilsErrors.dat (comments excluded)
+ * 
+ * DO NOT EDIT THE LINES BETWEEN //~Start and //~End!  ANY CHANGES WILL BE OVERWRITTEN.
+ */
+
+#define PS_ERRORNAME_DOMAIN "psLib.sysUtils."
+
+//~Start #define PS_ERRORTEXT_$1 "$2"
+#define PS_ERRORTEXT_psLogMsg_DESTINATION_MALFORMED "The specified destination, %s, is malformed."
+#define PS_ERRORTEXT_psLogMsg_DEST_LOCATION_INVALID "The location, %s, for protocol 'dest' is invalid."
+#define PS_ERRORTEXT_psLogMsg_OPEN_FILE_FAILED "Could not open file '%s' for output."
+#define PS_ERRORTEXT_psLogMsg_UNSUPPORTED_PROTOCOL "Do not know how to handle the protocol '%s'."
+#define PS_ERRORTEXT_psLogMsg_UNKNOWN_KEY "Unknown logging keyword %c."
+#define PS_ERRORTEXT_psMemory_NULL_BLOCK "NULL memory block found."
+#define PS_ERRORTEXT_psMemory_DEREF_BLOCK_USE "Memory block %ld was freed but still being used."
+#define PS_ERRORTEXT_psMemory_UNDERFLOW "Memory block %ld is corrupted; buffer underflow detected."
+#define PS_ERRORTEXT_psMemory_OVERFLOW "Memory block %ld is corrupted; buffer overflow detected."
+#define PS_ERRORTEXT_psMemory_MULTIPLE_FREE "Block %ld, allocated at %s:%d, freed multiple times at %s:%d."
+#define PS_ERRORTEXT_psString_NCHAR_NEGATIVE "Can not copy a negative number of characters (%d)."
+#define PS_ERRORTEXT_psTrace_NULL_SUBCOMPONENT "Sub-component %d of node %s in trace tree is NULL."
+#define PS_ERRORTEXT_psTrace_NULL_TRACETREE "Function %s called on a NULL trace level tree."
+#define PS_ERRORTEXT_psTrace_ADD_NULL_COMPONENT "Failed to add null component to trace tree."
+#define PS_ERRORTEXT_psTrace_MALFORMED_COMPONENT_NAME "Failed to add '%s' to the root component tree; component must start with '.'."
+#define PS_ERRORTEXT_psTrace_FAILED_TO_ADD_COMPONENT "Failed to set trace level (%d) to '%s'."
+#define PS_ERRORTEXT_psErrorCode_NULL_ERRORDESCRIPTION "Specified psErrorDescription pointer can not be NULL."
+#define PS_ERRORTEXT_psErrorCode_ERRORCODE_REGISTER_FAILED "Failed to add input psErrorDescription at array index %d"
+//~End
+
+#endif
Index: /branches/rel3/psLib/src/sysUtils/psTrace.c
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psTrace.c	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psTrace.c	(revision 2163)
@@ -0,0 +1,520 @@
+/** @file psTrace.c
+ *  \brief basic run-time trace facilities
+ *  \ingroup LogTrace
+ *
+ *  This file will hold the code for procedures to insert
+ *  trace messages into the code.
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.35 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-20 22:03:35 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/*****************************************************************************
+    NOTES:
+ In the SRD, higher trace levels correspond to a numerically lower trace
+ value in the code.  This is a bit confusing.  For example, a high-level
+ message might be something like "Begin Processing".  The module programmer
+ might give that a numerically low trace level, such as 1, so then any
+ non-zero trace level in that code component will display thatmessage.
+ 
+ We build a tree of trace components.  Every node in the tree has a
+ depth, which is it's distance from the root.  However, this is not
+ not the same thing as a node's "level", which corresponds to the
+ trace level of that node.
+ 
+I think the following is the correct behavior, but not sure:
+    PS_UNKNOWN_TRACE_LEVEL: We never set the level of a component to this
+    value.  This value is only used when psTraceGetLevel is called with
+    a bad component name, or if the component root is undefined, I think.
+ 
+    PS_DEFAULT_TRACE_LEVEL: This should only be used when adding the
+    intermediate components of a long name.  Ie. the "B" in .A.B.C
+ 
+ *****************************************************************************/
+
+#ifndef PS_NO_TRACE
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include "psMemory.h"
+#include "psTrace.h"
+#include "psString.h"
+#include "psError.h"
+#include "psLogMsg.h"
+
+#include "psSysUtilsErrors.h"
+
+static p_psComponent* cRoot = NULL; // The root of the trace component
+static FILE *traceFP = NULL;        // File destination for messages.
+
+static void componentFree(p_psComponent* comp);
+static p_psComponent* componentAlloc(const char *name, int level);
+
+/*****************************************************************************
+componentAlloc(): allocate memory for a new node, and initialize members.
+ *****************************************************************************/
+static p_psComponent* componentAlloc(const char *name, int level)
+{
+    p_psComponent* comp = psAlloc(sizeof(p_psComponent));
+
+    p_psMemSetPersistent(comp,true);
+    p_psMemSetDeallocator(comp, (psFreeFcn) componentFree);
+    comp->name = psStringCopy(name);
+    p_psMemSetPersistent((void*)comp->name,true);
+    comp->level = level;
+    comp->n = 0;
+    comp->subcomp = NULL;
+    return comp;
+}
+
+/*****************************************************************************
+componentFree(): free the current node in the root tree, and all children
+nodes as well.
+ *****************************************************************************/
+static void componentFree(p_psComponent* comp)
+{
+    if (comp == NULL) {
+        return;
+    }
+
+    if (comp->subcomp != NULL) {
+        for (int i = 0; i < comp->n; i++) {
+            p_psMemSetPersistent(comp->subcomp[i],false);
+            psFree(comp->subcomp[i]);
+        }
+        p_psMemSetPersistent(comp->subcomp,false);
+        psFree(comp->subcomp);
+    }
+
+    p_psMemSetPersistent((void*)comp->name,false);
+    psFree((void*)comp->name);
+}
+
+/*****************************************************************************
+initTrace(): simply initialize the component root tree.
+*****************************************************************************/
+static void initTrace(void)
+{
+    if (cRoot == NULL) {
+        cRoot = componentAlloc(".", PS_DEFAULT_TRACE_LEVEL);
+    }
+}
+
+/*****************************************************************************
+Set all trace levels to zero.
+ 
+XXX: Currently, no function calls this routine.
+ *****************************************************************************/
+void p_psTraceReset(p_psComponent* currentNode)
+{
+    int i = 0;
+
+    if (NULL == currentNode) {
+        return;
+    }
+
+    currentNode->level = 0;
+    for (i = 0; i < currentNode->n; i++) {
+        if (NULL == currentNode->subcomp[i]) {
+            psLogMsg(PS_ERRORNAME_DOMAIN "p_psTraceReset", PS_LOG_WARN,
+                     PS_ERRORTEXT_psTrace_NULL_SUBCOMPONENT,
+                     i, currentNode->name);
+        } else {
+            p_psTraceReset(currentNode->subcomp[i]);
+        }
+    }
+    return;
+}
+
+/*****************************************************************************
+Set all trace levels to zero.
+ *****************************************************************************/
+void psTraceReset()
+{
+    psFree(cRoot);
+    cRoot = NULL;
+}
+
+/*****************************************************************************
+componentAdd(): Adds the component named "addNodeName" to the root tree.
+ 
+NOTE: replace the call to strsep() with a call to strtok(), which conforms
+to ANSI-C.
+ *****************************************************************************/
+static bool componentAdd(const char *addNodeName, int level)
+{
+    int i = 0;                  // Loop index variable.
+    char name[strlen(addNodeName) + 1]; // buffer for writeable copy.
+    char *pname = name;
+    char *firstComponent = NULL;        // first component of name
+    p_psComponent* currentNode = cRoot;
+    int nodeExists = 0;
+
+    // XXX: Verify that this is the correct behavior.
+    if (strcmp("", addNodeName) == 0) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "componentAdd",PS_ERR_BAD_PARAMETER_NULL,true,
+                   PS_ERRORTEXT_psTrace_ADD_NULL_COMPONENT);
+        return false;
+    }
+
+    // Is this the root node? If so, simply set level and return.
+    if (strcmp(".", addNodeName) == 0) {
+        cRoot->level = level;
+        return true;
+    }
+
+    if (addNodeName[0] != '.') {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "componentAdd",PS_ERR_BAD_PARAMETER_VALUE,true,
+                   PS_ERRORTEXT_psTrace_MALFORMED_COMPONENT_NAME,
+                   addNodeName);
+        return false;
+    }
+
+    strcpy(name, addNodeName);
+    pname = &name[1];
+    // Iterate through the components of addNodeName.  Strip off the first
+    // component of the name, find that in the root tree, or add it if it
+    // does not exist, then move to the next component in the name.
+
+    while (pname != NULL) {
+        firstComponent = strsep(&pname, ".");
+        nodeExists = 0;
+        for (i = 0; i < currentNode->n; i++) {
+            if (strcmp(currentNode->subcomp[i]->name, firstComponent) == 0) {
+                currentNode = currentNode->subcomp[i];
+                nodeExists = 1;
+                if (pname == NULL) {
+                    currentNode->level = level;
+                }
+            }
+        }
+
+        if (nodeExists == 0) {
+            currentNode->subcomp = psRealloc(currentNode->subcomp,
+                                             (currentNode->n + 1) * sizeof(p_psComponent* ));
+            p_psMemSetPersistent(currentNode->subcomp,true);
+
+            currentNode->n = (currentNode->n) + 1;
+
+            if (pname == NULL) {
+                // This is the final component to add.
+                currentNode->subcomp[(currentNode->n) - 1] = componentAlloc(firstComponent, level);
+            } else {
+                // We are adding an intermediate component.  The trace level
+                // is not defined.  An undefined trace level inherits the
+                // trace level of it's parent.  However, we do not set that
+                // specifically here since that would inheritance to be a
+                // static, one-time, type of behavior.
+
+                currentNode->subcomp[(currentNode->n) - 1] = componentAlloc(firstComponent, PS_DEFAULT_TRACE_LEVEL);
+            }
+            currentNode = currentNode->subcomp[(currentNode->n) - 1];
+        }
+    }
+
+    return true;
+}
+
+/*****************************************************************************
+    psSetTraceLevel(): add the component named "comp" to the component tree,
+ if it is not already there, and set it's trace level to "level".
+ 
+    NOTE: We modified this so that the user may omit the leading "," in a
+    component name.  Since the code was already implemented assuming the "."
+    was required, rather than change all that code, in this function, I
+    simply add a leading "." to the component name if there is none.
+ 
+    Input:
+ comp
+ level
+    Output:
+ none
+    Returns:
+ zero
+*****************************************************************************/
+bool psTraceSetLevel(const char *comp,   // component of interest
+                     int level)  // desired trace level
+{
+    char *compName = NULL;
+
+    // If the root component tree does not exist, then initialize it.
+    if (cRoot == NULL) {
+        initTrace();
+    }
+
+    // If the component name has no leading dot, then supply it.
+    if (comp[0] != '.') {
+        compName = (char *) psAlloc(10 + strlen(comp));
+        strcpy(compName, ".");
+        compName = strcat(compName, comp);
+    } else {
+        compName = (char *) comp;
+    }
+
+    // Add the new component to the component tree.
+    if ( !componentAdd(compName, level) ) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psTraceSetLevel",
+                   PS_ERR_UNKNOWN,
+                   false,
+                   PS_ERRORTEXT_psTrace_FAILED_TO_ADD_COMPONENT,
+                   level,
+                   compName);
+        if (comp[0] != '.') {
+            psFree(compName);
+        }
+        return false;
+    }
+
+    if (comp[0] != '.') {
+        psFree(compName);
+    }
+
+    return true;
+}
+
+/*****************************************************************************
+    doGetTraceLevel()
+ This function recursively searches the root component tree for the
+ component named "name", which is supplied by a parameter.  If it
+ finds that component, it returns the level of that component.
+ Otherwise, it returns ???.
+ 
+    NOTE: We modified this so that the user may omit the leading "," in a
+    component name.  Since the code was already implemented assuming the "."
+    was required, rather than change all that code, in this function, I
+    simply add a leading "." to the component name if there is none.
+ 
+    Inputs:
+ name:
+    Outputs:
+ none
+    Returns:
+ The trace level of the "name" component.
+ *****************************************************************************/
+static int doGetTraceLevel(const char *aname)
+{
+    char name[strlen(aname) + 1];       // need a writeable copy: for strsep()
+    char *pname = name;
+    char *firstComponent = NULL;        // first component of name
+    p_psComponent* currentNode = cRoot;
+    int i = 0;
+    int defaultLevel = 0;
+
+    if (NULL == currentNode) {
+        return (PS_UNKNOWN_TRACE_LEVEL);
+    }
+
+    if (strcmp(".", aname) == 0) {
+        return (cRoot->level);
+    }
+
+    if (aname[0] != '.') {
+        return (PS_UNKNOWN_TRACE_LEVEL);
+    }
+
+    defaultLevel = cRoot->level;
+    strcpy(name, aname);
+    pname = &name[1];
+    while (pname != NULL) {
+        firstComponent = strsep(&pname, ".");
+        for (i = 0; i < currentNode->n; i++) {
+            if (NULL == currentNode->subcomp[i]) {
+                psLogMsg(PS_ERRORNAME_DOMAIN "p_psTraceReset", PS_LOG_WARN,
+                         PS_ERRORTEXT_psTrace_NULL_SUBCOMPONENT,
+                         i, currentNode->name);
+            }
+
+            if (strcmp(currentNode->subcomp[i]->name, firstComponent) == 0) {
+                currentNode = currentNode->subcomp[i];
+                // For level inheritance purpose, we save the level of this
+                // component if it is not DEFAULT.
+                if (currentNode->level != PS_DEFAULT_TRACE_LEVEL) {
+                    defaultLevel = currentNode->level;
+                }
+                // Determine if this is the last component:
+                if (pname == NULL) {
+                    if (currentNode->level != PS_DEFAULT_TRACE_LEVEL) {
+                        return (currentNode->level);
+                    } else {
+                        return(defaultLevel);
+                    }
+                }
+            }
+        }
+    }
+    return(defaultLevel);
+}
+
+/*****************************************************************************
+    psTraceLevelGet()
+ Return a trace level of "name" in the root component tree.  If the
+ exact string of components in "name" does not exist in the root
+ tree, we return the deepest level of the match.
+    Input:
+ name
+    Output:
+ none
+    Return:
+ The level of "name" in the root component tree.
+ *****************************************************************************/
+int psTraceGetLevel(const char *name)
+{
+    char *compName = NULL;
+    int traceLevel;
+
+    if (cRoot == NULL) {
+        return (PS_UNKNOWN_TRACE_LEVEL);
+    }
+
+    // If the component name has no leading dot, then supply it.
+    if (name[0] != '.') {
+        compName = (char *) psAlloc(10 + strlen(name));
+        strcpy(compName, ".");
+        compName = strcat(compName, name);
+        traceLevel = doGetTraceLevel(compName);
+        psFree(compName);
+    } else {
+        // Search the component root tree, determine the trace level.
+        traceLevel = doGetTraceLevel(name);
+    }
+    return(traceLevel);
+}
+
+/*****************************************************************************
+    doPrintTraceLevels()
+ This function recursively searches the component tree supplied by the
+ parameter "comp" and prints the name and level of each component.
+    Inputs:
+ comp: a node in the component tree.
+ level: the level of that node
+    Outputs:
+ none
+    Returns:
+ null
+ *****************************************************************************/
+static void doPrintTraceLevels(const p_psComponent* comp,
+                               int depth,
+                               int defLevel)
+{
+    int i = 0;
+
+    if (comp->name[0] == '\0') {
+        return;
+    } else {
+        if (comp->level == PS_DEFAULT_TRACE_LEVEL) {
+            if (traceFP == NULL) {
+                printf("%*s%-*s %d\n", depth, "", 20 - depth, comp->name,
+                       defLevel);
+            } else {
+                fprintf(traceFP,"%*s%-*s %d\n", depth, "", 20 - depth, comp->name,
+                        defLevel);
+            }
+        } else {
+            if (traceFP == NULL) {
+                printf("%*s%-*s %d\n", depth, "", 20 - depth, comp->name,
+                       comp->level);
+            } else {
+                fprintf(traceFP, "%*s%-*s %d\n", depth, "", 20 - depth, comp->name,
+                        comp->level);
+            }
+        }
+    }
+
+    for (i = 0; i < comp->n; i++) {
+        if (comp->level == PS_DEFAULT_TRACE_LEVEL) {
+            doPrintTraceLevels(comp->subcomp[i], depth + 1, defLevel);
+        } else {
+            doPrintTraceLevels(comp->subcomp[i], depth + 1, comp->level);
+        }
+    }
+}
+
+
+/*****************************************************************************
+psPrintTraceLevels(): Simply print all the trace levels in the trace level
+component tree.
+Inputs:
+ none
+Outputs:
+ none
+Returns:
+ null
+*****************************************************************************/
+void psTracePrintLevels(void)
+{
+    if (cRoot == NULL) {
+        return;
+    }
+
+    doPrintTraceLevels(cRoot, 0, PS_DEFAULT_TRACE_LEVEL);
+}
+
+/*****************************************************************************
+p_psTrace(): we display the trace message to standard output if the trace
+level of that message, supplied by the parameter "level" is higher than the
+trace level that is currently associated with the component named by the
+parameter "comp".
+Input:
+ comp
+ level
+ ...  a printf-style output string.
+Output:
+ none
+Return:
+ null
+ *****************************************************************************/
+void p_psTrace(const char *comp,        // component being traced
+               int level,       // desired trace level
+               ...)             // arguments
+{
+    char *fmt = NULL;
+    va_list ap;
+    int i = 0;
+
+    if (NULL == comp) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psTrace", PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psTrace_NULL_TRACETREE,
+                   __func__);
+        return;
+    }
+    // Only display this message if it's trace level is less than the level
+    // of it's associatedcomponent.
+    if (level <= psTraceGetLevel(comp)) {
+        va_start(ap, level);
+
+        // The following functions get the variable list of parameters with
+        // which this function was called, and print them to the standard
+        // output.
+        fmt = va_arg(ap, char *);
+
+        if (traceFP != NULL) {
+            // We indent each message one space for each level of the message.
+            for (i = 0; i < level; i++) {
+                fprintf(traceFP, " ");
+            }
+            vfprintf(traceFP, fmt, ap);
+        } else {
+            // We indent each message one space for each level of the message.
+            for (i = 0; i < level; i++) {
+                putchar(' ');
+            }
+            vprintf(fmt, ap);
+        }
+        va_end(ap);
+    }
+    // NOTE: should we free *fmt as well? Read the man page.
+}
+
+void psTraceSetDestination(FILE * fp)
+{
+    traceFP = fp;
+}
+
+#endif
Index: /branches/rel3/psLib/src/sysUtils/psTrace.h
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psTrace.h	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psTrace.h	(revision 2163)
@@ -0,0 +1,92 @@
+/** @file psTrace.h
+ *  \brief basic run-time trace facilities
+ *  \ingroup LogTrace
+ *
+ *  This file will hold the prototypes for defining procedures to insert
+ *  trace messages into the code.
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.23 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-20 22:03:35 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_TRACE_H)
+#define PS_TRACE_H 1
+
+#define PS_UNKNOWN_TRACE_LEVEL -9999   // we don't know this name's level
+#define PS_DEFAULT_TRACE_LEVEL -1
+
+/** \addtogroup LogTrace
+ *  \{
+ */
+
+/** Functions **************************************************************/
+
+//#define PS_NO_TRACE 1   ///< to turn off all tracing
+
+#if defined(PS_NO_TRACE)
+#        define psTrace(facil, level, ...) (void)0
+/* do nothing */
+#        define p_psTrace(facil, level, ...)  (void)0
+/* do nothing */
+#        define psTraceSetLevel(facil,level) 0
+#        define psTraceGetLevel(facil) 0
+#        define psTraceReset() (void)0     /* do nothing */
+#        define psTraceFree() (void)0      /* do nothing */
+#        define psTracePrintLevels() (void)0
+/* do nothing */
+#        define psTraceSetDestination(fp) (void)0
+/* do nothing */
+#    else
+
+    /** Basic structure for the component tree.  A component is a string of the
+        form aaa.bbb.ccc, and may itself contain further subcomponents.  The
+        Component structure doesn't in fact contain it's full name, but only the
+        last part. */
+    typedef struct p_psComponent
+    {
+        const char *name;           // last part of name of component
+        int level;                  // trace level for this component
+        int n;                      // number of subcomponents
+        struct p_psComponent* *subcomp;     // next level of subcomponents
+    }
+p_psComponent;
+
+#ifndef DOXYGEN
+/// Send a trace message
+void p_psTrace(const char *facil,       ///< facilty of interest
+               int myLevel,     ///< desired trace level
+               ...)             ///< trace message arguments
+;
+#endif
+
+/// Set trace level
+bool psTraceSetLevel(const char *facil,     ///< facilty of interest
+                     int level)     ///< desired trace level
+;
+
+/// Get the trace level
+int psTraceGetLevel(const char *facil)     ///< facilty of interest
+;
+
+/// Set all trace levels to zero (do not free nodes in the component tree).
+void psTraceReset();
+
+/// Free all nodes in the component tree.
+void psTraceFree();
+
+/// print trace levels
+void psTracePrintLevels(void);
+
+/// Set the destination of future trace messages.
+void psTraceSetDestination(FILE * fp);
+
+/* \} */// End of SystemGroup Functions
+
+#define psTrace(facil, level, ...) p_psTrace(facil, level, __VA_ARGS__)
+#endif
+
+#endif
Index: /branches/rel3/psLib/src/sysUtils/psType.h
===================================================================
--- /branches/rel3/psLib/src/sysUtils/psType.h	(revision 2163)
+++ /branches/rel3/psLib/src/sysUtils/psType.h	(revision 2163)
@@ -0,0 +1,215 @@
+
+/** @file  psType.h
+*
+*  @brief Contains support for basic types
+*
+*  This file defines common datatypes used throughout psLib.
+*
+*  @ingroup DataContainer
+*
+*  @author Robert DeSonia, MHPCC
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.22 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-06 21:40:13 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#ifndef PS_TYPE_H
+#define PS_TYPE_H
+
+#include <complex.h>
+#include <stdint.h>
+#include <float.h>
+
+/// @addtogroup DataContainer
+/// @{
+
+/******************************************************************************/
+
+/*  TYPE DEFINITIONS                                                          */
+
+/******************************************************************************/
+
+/** Basic data types used by the containers.
+ *
+ * The basic types of the primitives used by psLib are defined within this enum. This enum is in turn used by
+ * the psType struct.
+ *
+ */
+
+typedef uint8_t psU8;                  ///< 8-bit unsigned int
+typedef uint16_t psU16;                ///< 16-bit unsigned int
+typedef uint32_t psU32;                ///< 32-bit unsigned int
+typedef uint64_t psU64;                ///< 64-bit unsigned int
+typedef int8_t psS8;                   ///< 8-bit signed int
+typedef int16_t psS16;                 ///< 16-bit signed int
+typedef int32_t psS32;                 ///< 32-bit signed int
+typedef int64_t psS64;                 ///< 64-bit signed int
+typedef float psF32;                   ///< 32-bit floating point
+typedef double psF64;                  ///< 64-bit floating point
+typedef float _Complex psC32;          ///< complex with 32-bit floating point Real and Imagary numbers
+typedef double _Complex psC64;         ///< complex with 64-bit floating point Real and Imagary numbers
+typedef void *psPTR;                   ///< void pointer
+
+typedef enum {
+    PS_TYPE_S8 = 0x0101,               ///< Character.
+    PS_TYPE_S16 = 0x0102,              ///< Short integer.
+    PS_TYPE_S32 = 0x0104,              ///< Integer.
+    PS_TYPE_S64 = 0x0108,              ///< Long integer.
+    PS_TYPE_U8 = 0x0301,               ///< Unsigned character.
+    PS_TYPE_U16 = 0x0302,              ///< Unsigned short integer.
+    PS_TYPE_U32 = 0x0304,              ///< Unsigned integer.
+    PS_TYPE_U64 = 0x0308,              ///< Unsigned long integer.
+    PS_TYPE_F32 = 0x0404,              ///< Single-precision Floating point.
+    PS_TYPE_F64 = 0x0408,              ///< Double-precision floating point.
+    PS_TYPE_C32 = 0x0808,              ///< Complex numbers consisting of single-precision floating point.
+    PS_TYPE_C64 = 0x0810,              ///< Complex numbers consisting of double-precision floating point.
+    PS_TYPE_PTR = 0x0000               ///< Something else that's not supported for arithmetic.
+} psElemType;
+
+#define PS_TYPE_MASK PS_TYPE_U8        /**< the psElemType to use for mask image */
+#define PS_TYPE_MASK_DATA U8           /**< the data member to use for mask image */
+#define PS_TYPE_MASK_NAME "psU8"       /**< the data type for mask as a string */
+
+typedef psU8 psMaskType;               ///< the C datatype for a mask image
+
+
+#define PS_MIN_S8        INT8_MIN      /**< minimum valid psS8 value */
+#define PS_MIN_S16       INT16_MIN     /**< minimum valid psS16 value */
+#define PS_MIN_S32       INT32_MIN     /**< minimum valid psS32 value */
+#define PS_MIN_S64       INT64_MIN     /**< minimum valid psS64 value */
+#define PS_MIN_U8        0             /**< minimum valid psU8 value */
+#define PS_MIN_U16       0             /**< minimum valid psU16 value */
+#define PS_MIN_U32       0             /**< minimum valid psU32 value */
+#define PS_MIN_U64       0             /**< minimum valid psU64 value */
+#define PS_MIN_F32       -FLT_MAX      /**< minimum valid psF32 value */
+#define PS_MIN_F64       -DBL_MAX      /**< minimum valid psF64 value */
+#define PS_MIN_C32       -FLT_MAX      /**< minimum valid real or imaginary psC32 value */
+#define PS_MIN_C64       -DBL_MAX      /**< minimum valid real or imaginary psC32 value */
+
+#define PS_MAX_S8        INT8_MAX      /**< maximum valid psS8 value */
+#define PS_MAX_S16       INT16_MAX     /**< maximum valid psS16 value */
+#define PS_MAX_S32       INT32_MAX     /**< maximum valid psS32 value */
+#define PS_MAX_S64       INT64_MAX     /**< maximum valid psS64 value */
+#define PS_MAX_U8        UINT8_MAX     /**< maximum valid psU8 value */
+#define PS_MAX_U16       UINT16_MAX    /**< maximum valid psU16 value */
+#define PS_MAX_U32       UINT32_MAX    /**< maximum valid psU32 value */
+#define PS_MAX_U64       UINT64_MAX    /**< maximum valid psU64 value */
+#define PS_MAX_F32       FLT_MAX       /**< maximum valid psF32 value */
+#define PS_MAX_F64       DBL_MAX       /**< maximum valid psF64 value */
+#define PS_MAX_C32       FLT_MAX       /**< maximum valid real or imaginary psC32 value */
+#define PS_MAX_C64       DBL_MAX       /**< maximum valid real or imaginary psC32 value */
+
+#define PS_TYPE_S8_NAME  "psS8"
+#define PS_TYPE_S16_NAME "psS16"
+#define PS_TYPE_S32_NAME "psS32"
+#define PS_TYPE_S64_NAME "psS64"
+#define PS_TYPE_U8_NAME  "psU8"
+#define PS_TYPE_U16_NAME "psU16"
+#define PS_TYPE_U32_NAME "psU32"
+#define PS_TYPE_U64_NAME "psU64"
+#define PS_TYPE_F32_NAME "psF32"
+#define PS_TYPE_F64_NAME "psF64"
+#define PS_TYPE_C32_NAME "psC32"
+#define PS_TYPE_C64_NAME "psC64"
+#define PS_TYPE_PTR_NAME "psPTR"
+
+#define PS_TYPE_NAME(value,type) \
+switch(type) { \
+case PS_TYPE_S8: \
+    value = PS_TYPE_S8_NAME; \
+    break; \
+case PS_TYPE_S16: \
+    value = PS_TYPE_S16_NAME; \
+    break; \
+case PS_TYPE_S32: \
+    value = PS_TYPE_S32_NAME; \
+    break; \
+case PS_TYPE_S64: \
+    value = PS_TYPE_S64_NAME; \
+    break; \
+case PS_TYPE_U8: \
+    value = PS_TYPE_U8_NAME; \
+    break; \
+case PS_TYPE_U16: \
+    value = PS_TYPE_U16_NAME; \
+    break; \
+case PS_TYPE_U32: \
+    value = PS_TYPE_U32_NAME; \
+    break; \
+case PS_TYPE_U64: \
+    value = PS_TYPE_U64_NAME; \
+    break; \
+case PS_TYPE_F32: \
+    value = PS_TYPE_F32_NAME; \
+    break; \
+case PS_TYPE_F64: \
+    value = PS_TYPE_F64_NAME; \
+    break; \
+case PS_TYPE_C32: \
+    value = PS_TYPE_C32_NAME; \
+    break; \
+case PS_TYPE_C64: \
+    value = PS_TYPE_C64_NAME; \
+    break; \
+case PS_TYPE_PTR: \
+    value = PS_TYPE_PTR_NAME; \
+    break; \
+default: \
+    value = "unknown"; \
+};
+
+/// Macro to get the bad pixel reason code (stored as part of mask value)
+#define PS_BADPIXEL_BITMASK 0x0f
+#define PS_GET_BADPIXEL(maskValue) (maskValue & PS_BADPIXEL_BITMASK)
+
+#define PS_IS_BADPIXEL(maskValue) (PS_GET_BADPIXEL(maskValue) != 0)
+
+/// Macro to apply a bad pixel reason code to mask image
+#define PS_SET_BADPIXEL(maskValue, reasonCode) \
+{ \
+    maskValue = (psMaskType)((reasonCode & PS_BADPIXEL_BITMASK) | (maskValue & ~PS_BADPIXEL_BITMASK)); \
+}
+
+/// Macro to determine if the psElemType is an integer.
+#define PS_IS_PSELEMTYPE_INT(x) ((x & 0x100) == 0x100)
+/// Macro to determine if the psElemType is unsigned.
+#define PS_IS_PSELEMTYPE_UNSIGNED(x) ((x & 0x200) == 0x200)
+/// Macro to determine if the psElemType is a real (non-complex) floating-point type.
+#define PS_IS_PSELEMTYPE_REAL(x) ((x & 0x400) == 0x400)
+/// Macro to determine if the psElemType is complex number type.
+#define PS_IS_PSELEMTYPE_COMPLEX(x) ((x & 0x800) == 0x800)
+/// Macro to determine the storage size, in bytes, of the psElemType.
+#define PSELEMTYPE_SIZEOF(x) ( (x==PS_TYPE_PTR) ? sizeof(void*) :(x & 0xFF) )
+
+/** Dimensions of a data type.
+ *
+ * The dimensions of containers used by psLib are defined within this enum. This enum is used by the psType
+struct. *
+ */
+typedef enum {
+    PS_DIMEN_SCALAR,            ///< Scalar.
+    PS_DIMEN_VECTOR,            ///< Vector.
+    PS_DIMEN_TRANSV,            ///< Transposed vector.
+    PS_DIMEN_IMAGE,             ///< Image.
+    PS_DIMEN_OTHER              ///< Something else that's not supported for arithmetic.
+} psDimen;
+
+/** The type of a data type.
+ *
+ * All psLib complex types consist of primitive components. This struct provides the description of those
+ * primitives.
+ *
+ */
+typedef struct
+{
+    psElemType type;            ///< Primitive type.
+    psDimen dimen;              ///< Dimensionality.
+}
+psType;
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/types/psArray.c
===================================================================
--- /branches/rel3/psLib/src/types/psArray.c	(revision 2163)
+++ /branches/rel3/psLib/src/types/psArray.c	(revision 2163)
@@ -0,0 +1,136 @@
+
+/** @file  psArray.c
+ *
+ *  @brief Contains support for basic vector types
+ *
+ *  This file defines the basic type for a vector struct and functions useful
+ *  in manupulating vectors.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-28 23:26:48 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/******************************************************************************/
+
+/*  INCLUDE FILES                                                             */
+
+/******************************************************************************/
+#include<stdlib.h>                         // for qsort, etc.
+#include<string.h>
+
+#include "psMemory.h"
+#include "psError.h"
+#include "psArray.h"
+#include "psLogMsg.h"
+
+#include "psCollectionsErrors.h"
+
+/*****************************************************************************/
+
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+
+/*****************************************************************************/
+static void arrayFree(psArray* restrict psArr);
+
+/*****************************************************************************/
+
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+
+/*****************************************************************************/
+psArray* psArrayAlloc(unsigned int nalloc)
+{
+    psArray* psArr = NULL;
+
+    // Create vector struct
+    psArr = (psArray* ) psAlloc(sizeof(psArray));
+    p_psMemSetDeallocator(psArr, (psFreeFcn) arrayFree);
+
+    psArr->nalloc = nalloc;
+    psArr->n = nalloc;
+
+    // Create vector data array
+    psArr->data = psAlloc(nalloc * sizeof(psPTR));
+
+    return psArr;
+}
+
+psArray* psArrayRealloc(psArray* restrict in, unsigned int nalloc)
+{
+    if (in == NULL) {
+        return psArrayAlloc(nalloc);
+    } else if (in->nalloc != nalloc) {     // No need to realloc to same size
+        if (nalloc < in->n) {
+            for (int i = nalloc; i < in->n; i++) {      // For reduction in vector size
+                psFree(in->data[i]);
+            }
+            in->n = nalloc;
+        }
+        // Realloc after decrementation to avoid accessing freed array elements
+        in->data = psRealloc(in->data, nalloc * sizeof(psPTR));
+        in->nalloc = nalloc;
+    }
+
+    return in;
+}
+
+static void arrayFree(psArray* restrict psArr)
+{
+    if (psArr == NULL) {
+        return;
+    }
+
+    psArrayElementFree(psArr);
+
+    psFree(psArr->data);
+}
+
+bool psArrayRemove(psArray* psArr,
+                   psPTR data)
+{
+    bool success = false;
+
+    if (psArr == NULL) {
+        return success;
+    }
+
+    int n = psArr->n;
+    psPTR* psArrData = psArr->data;
+    for (int i = n-1; i<0; i--) {
+        if (psArrData[i] == data) {
+            memmove(psArrData[i],psArrData[i+1],(n-i-1)*sizeof(psPTR));
+            n--;
+            success = true;
+        }
+    }
+    psArr->n = n; // reset the array size to indicate the removed item(s)
+
+    return success;
+}
+
+void psArrayElementFree(psArray* restrict psArr)
+{
+
+    if (psArr == NULL) {
+        return;
+    }
+
+    for (int i = 0; i < psArr->n; i++) {
+        psFree(psArr->data[i]);
+        psArr->data[i] = NULL;
+    }
+}
+
+psArray* psArraySort(psArray* in, psComparePtrFcn compare)
+{
+    if (in == NULL) {
+        return NULL;
+    }
+
+    qsort(in->data, in->n, sizeof(psPTR), (int (*)(const void *, const void *))compare);
+
+    return in;
+}
Index: /branches/rel3/psLib/src/types/psArray.h
===================================================================
--- /branches/rel3/psLib/src/types/psArray.h	(revision 2163)
+++ /branches/rel3/psLib/src/types/psArray.h	(revision 2163)
@@ -0,0 +1,120 @@
+
+/** @file  psArray.h
+ *
+ *  @brief Contains basic array definitions and operations
+ *
+ *  This file defines the basic type for a array struct and functions useful
+ *  in manupulating arrays.
+ *
+ *  @ingroup Array
+ *
+ *  @author Robert DeSonia, MHPCC
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-28 23:26:48 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PS_ARRAY_H
+#define PS_ARRAY_H
+
+#include<stdbool.h>
+
+#include "psType.h"
+#include "psCompare.h"
+
+/// @addtogroup Array
+/// @{
+
+/** An array to support primitive types.
+ *
+ * Struct for maintaining an array of frequently used primitive types.
+ *
+ */
+typedef struct
+{
+    unsigned int nalloc;        ///< Total number of elements available.
+    unsigned int n;             ///< Number of elements in use.
+    psPTR* data;                ///< An Array of pointer elements
+}
+psArray;
+
+/*****************************************************************************/
+
+/* FUNCTION PROTOTYPES                                                       */
+
+/*****************************************************************************/
+
+/** Allocate an array.
+ *
+ * Uses psLib memory allocation functions to create an array collection of 
+ * data
+ *
+ * @return psArray* : Pointer to psArray.
+ *
+ */
+psArray* psArrayAlloc(
+    unsigned int nalloc                ///< Total number of elements to make available.
+);
+
+/** Reallocate an array.
+ *
+ * Uses psLib memory allocation functions to reallocate an array collection 
+ * of data. 
+ *
+ * @return psArray* : Pointer to psArray.
+ *
+ */
+psArray* psArrayRealloc(
+    psArray* restrict psArr,           ///< array to reallocate.
+    unsigned int nalloc                ///< Total number of elements to make available.
+);
+
+/** Remove an element from the array
+ *
+ *  Finds and removes the specified data pointer from the list.  
+ *
+ * @return bool:  TRUE if the specified data pointer was found and removed, 
+ *                otherwise FALSE.
+ *
+ */
+bool psArrayRemove(
+    psArray* psArr,                    ///< array to operate on
+    psPTR data                         ///< the data pointer to remove from psArray
+);
+
+/** Deallocate/Dereference elements of an array.
+ *
+ * Uses psLib memory allocation functions to deallocate/dereference elements 
+ * of a array of void pointers.  The array psArr is not freed, and its elements
+ * will all be set to NULL.
+ *
+ */
+void psArrayElementFree(
+    psArray* restrict psArr            ///< Void pointer array to destroy.
+);
+
+/** Sort the array according to an external compare function.
+ *
+ *  Sorts an array via the specification of a comparison function
+ *  to specify how the objects on the array should be sorted.
+ *
+ *  The comparison function must return an integer less than, equal to, or 
+ *  greater than zero if the first argument is considered to be respectively 
+ *  less than, equal to, or greater than the second. 
+ *
+ *  If two members compare as equal, their order in the sorted array is 
+ *  undefined.
+ *
+ *  @return psArray* The sorted array.
+ */
+psArray* psArraySort(
+    psArray* in,                       ///< input array to sort.
+    psComparePtrFcn compare            ///< the compare function
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/types/psBitSet.c
===================================================================
--- /branches/rel3/psLib/src/types/psBitSet.c	(revision 2163)
+++ /branches/rel3/psLib/src/types/psBitSet.c	(revision 2163)
@@ -0,0 +1,321 @@
+/** @file  psBitSet.c
+ *
+ *  @brief Creates an array of bytes of arbitrary length for storing individual bits.
+ *
+ *  Bit masks are useful tools for toggling various flags and options. This set of functions module provides
+ *  a mechanism to create an array of bits of arbitrary length and manipulate them with basic binary
+ *  operations. A print function is also provided to display the entire set of bits in binary format as a
+ *  string.
+ *
+ *  @author Ross Harman, MHPCC
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-21 23:17:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+#include <stdbool.h>
+
+#include "psBitSet.h"
+#include "psMemory.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psString.h"
+
+#include "psCollectionsErrors.h"
+
+enum {
+    UNKNOWN_OP,
+    AND_OP,
+    OR_OP,
+    XOR_OP,
+    NOT_OP
+};
+
+static void bitSetFree(psBitSet* restrict inBitSet);
+
+/** Private function to create a mask.
+ *
+ *  Creates an eight bit mask with the given bit set. All other bits in the byte are zero. The input bit uses
+ *  zero-based indexing, and is the cumulitive index within the array, not the localized byte's bit position.
+ *
+ *  @return  char*: Pointer to byte in which bit is contained.
+ */
+static char mask(int bit)
+{
+    char mask = (char)0x01;
+
+    // Ignore splint warning about negative bit shifts
+    /* @i@ */
+    mask = mask << (bit % 8);
+
+    return mask;
+}
+
+static void bitSetFree(psBitSet* restrict inBitSet)
+{
+    if (inBitSet == NULL) {
+        return;
+    }
+    psFree(inBitSet->bits);
+}
+
+psBitSet* psBitSetAlloc(int n)
+{
+    int numBytes = 0;
+    psBitSet* newObj = NULL;
+
+    if (n < 0) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetAlloc",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psBitSet_ALLOC_NEG_SIZE,
+                   n);
+        return NULL;
+    }
+
+    numBytes = ceil(n / 8.0);
+    newObj = psAlloc(sizeof(psBitSet));
+    p_psMemSetDeallocator(newObj, (psFreeFcn) bitSetFree);
+    newObj->n = numBytes;
+
+    // Ignore splint warning about releasing pointer members, since they've not been allocated yet
+    /* @i@ */
+    newObj->bits = psAlloc(sizeof(char) * numBytes);
+
+    memset(newObj->bits, 0, numBytes);
+
+    return newObj;
+}
+
+psBitSet* psBitSetSet(psBitSet* inBitSet,
+                      int bit)
+{
+    char *byte = NULL;
+
+    if (inBitSet == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetSet",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psBitSet_SET_NULL);
+        return inBitSet;
+    } else if ( (bit < 0) ||
+                (bit > inBitSet->n * 8 - 1) ) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetSet",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psBitSet_BIT_OUTOFRANGE,
+                   bit,inBitSet->n * 8 - 1);
+        return inBitSet;
+    }
+    // Variable byte is the byte in the array that contains the bit to be set
+    byte = inBitSet->bits + bit / 8;
+    *byte |= mask(bit);
+
+    return inBitSet;
+}
+
+psBitSet* psBitSetClear(psBitSet* inBitSet,
+                        int bit)
+{
+    char *byte = NULL;
+
+    if (inBitSet == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetClear",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psBitSet_SET_NULL);
+        return inBitSet;
+    } else if ( (bit < 0) ||
+                (bit > inBitSet->n * 8 - 1) ) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetClear",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psBitSet_BIT_OUTOFRANGE,
+                   bit,inBitSet->n * 8 - 1);
+        return inBitSet;
+    }
+    // Variable byte is the byte in the array that contains the bit to be set
+    byte = inBitSet->bits + bit / 8;
+    *byte &= ! mask(bit);
+
+    return inBitSet;
+}
+
+bool psBitSetTest(const psBitSet* inBitSet,
+                  int bit)
+{
+    char *byte = NULL;
+
+    if (inBitSet == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetTest",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psBitSet_SET_NULL);
+        return false;
+    } else if ( (bit < 0) ||
+                (bit > inBitSet->n * 8 - 1) ) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetTest",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psBitSet_BIT_OUTOFRANGE,
+                   bit,inBitSet->n * 8 - 1);
+        return false;
+    }
+
+    // Variable byte is the byte in the array that contains the bit to be tested
+    byte = inBitSet->bits + bit / 8;
+    return ((*byte & mask(bit)) != 0);
+}
+
+psBitSet* psBitSetOp(psBitSet* outBitSet,
+                     const psBitSet* restrict inBitSet1,
+                     char *operator,
+                     const psBitSet* restrict inBitSet2)
+{
+    int i = 0;
+    int n = 0;
+    char* outBits = NULL;
+    char* inBits1 = NULL;
+    char* inBits2 = NULL;
+    int op = UNKNOWN_OP;
+
+    if (inBitSet1 == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetOp",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psBitSet_FIRST_OPERAND_NULL);
+        psFree(outBitSet);
+        return NULL;
+    }
+    inBits1 = inBitSet1->bits;
+
+    if (operator == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetOp",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psBitSet_OPERATOR_NULL);
+        psFree(outBitSet);
+        return NULL;
+    }
+
+    // make operator all caps
+    int tempStrLen = strlen(operator);
+    char* tempStr = psAlloc(tempStrLen+1);
+
+    for (int lcv=0;lcv<tempStrLen;lcv++) {
+        tempStr[lcv] = (char)toupper(operator[lcv]);
+    }
+    tempStr[tempStrLen] = '\0';
+
+    // parse the operator
+    if (strcmp(operator,"AND")==0) {
+        op = AND_OP;
+    } else if (strcmp(operator,"OR")==0) {
+        op = OR_OP;
+    } else if (strcmp(operator,"XOR")==0) {
+        op = XOR_OP;
+    } else if (strcmp(operator,"NOT")==0) {
+        op = NOT_OP;
+    } else {
+        psFree(tempStr);
+        psFree(outBitSet);
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetOp",
+                   PS_ERR_BAD_PARAMETER_VALUE, true,
+                   PS_ERRORTEXT_psBitSet_OPERATOR_INVALID,
+                   operator);
+        return NULL;
+    }
+    psFree(tempStr);
+
+    if (op != NOT_OP) {
+        if (inBitSet2 == NULL) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetOp",
+                       PS_ERR_BAD_PARAMETER_NULL, true,
+                       PS_ERRORTEXT_psBitSet_SECOND_OPERAND_NULL);
+            psFree(outBitSet);
+            return NULL;
+        }
+
+        if (inBitSet1->n != inBitSet2->n) {
+            psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetOp",
+                       PS_ERR_BAD_PARAMETER_SIZE, true,
+                       PS_ERRORTEXT_psBitSet_OPERANDS_SIZE_DIFFER);
+            psFree(outBitSet);
+            return NULL;
+        }
+        inBits2 = inBitSet2->bits;
+    }
+
+    if (outBitSet == NULL) {
+        outBitSet = psBitSetAlloc(inBitSet1->n*8);
+    } else if (outBitSet->n != inBitSet1->n) {
+        outBitSet->n = inBitSet1->n;
+        outBitSet->bits = psRealloc(outBitSet->bits, inBitSet1->n);
+    }
+
+    n = outBitSet->n;
+    outBits = outBitSet->bits;
+
+    switch (op) {
+    case AND_OP:
+        for (i = 0; i < n; i++) {
+            outBits[i] = inBits1[i] & inBits2[i];
+        }
+        break;
+    case OR_OP:
+        for (i = 0; i < n; i++) {
+            outBits[i] = inBits1[i] | inBits2[i];
+        }
+        break;
+    case XOR_OP:
+        for (i = 0; i < n; i++) {
+            outBits[i] = inBits1[i] ^ inBits2[i];
+        }
+        break;
+    case NOT_OP:
+        for (i = 0; i < n; i++) {
+            outBits[i] = ~inBits1[i];
+        }
+        break;
+    default:
+        psAbort(PS_ERRORNAME_DOMAIN "psBitSetOp",
+                "Unexpected error - operator parsed successfully but not valid?");
+    }
+
+    return outBitSet;
+}
+
+psBitSet* psBitSetNot(psBitSet* outBitSet,
+                      const psBitSet* restrict inBitSet)
+{
+    if (inBitSet == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetNot",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psBitSet_OPERAND_NULL);
+        psFree(outBitSet);
+        return NULL;
+    }
+
+    outBitSet = psBitSetOp(outBitSet,inBitSet,"NOT",NULL);
+
+    if (outBitSet == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psBitSetNot",
+                   PS_ERR_UNKNOWN, false,
+                   PS_ERRORTEXT_psBitSet_NOT_OP_FAILED);
+    }
+
+    return outBitSet;
+}
+
+char *psBitSetToString(const psBitSet* restrict inBitSet)
+{
+    int i = 0;
+    int numBits = inBitSet->n * 8;
+    char *outString = psAlloc((size_t) numBits + 1);
+
+    for (i = 0; i < numBits; i++) {
+        outString[numBits - i - 1] = psBitSetTest(inBitSet, i) ? '1' : '0';
+    }
+
+    outString[numBits] = 0;
+
+    return outString;
+}
Index: /branches/rel3/psLib/src/types/psBitSet.h
===================================================================
--- /branches/rel3/psLib/src/types/psBitSet.h	(revision 2163)
+++ /branches/rel3/psLib/src/types/psBitSet.h	(revision 2163)
@@ -0,0 +1,143 @@
+/** @file  psBitSet.h
+ *
+ *  @brief Creates an array of bytes of arbitrary length for storing individual bits.
+ *
+ *  Bit masks are useful tools for toggling various flags and options. This set of functions module provides
+ *  a mechanism to create an array of bits of arbitrary length and manipulate them with basic binary
+ *  operations. A print function is also provided to display the entire set of bits in binary format as a
+ *  string.
+ *
+ *  @ingroup BitSet
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-14 20:01:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PSBITSET_H
+#define PSBITSET_H
+
+/// @addtogroup BitSet
+/// @{
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+/** Struct containing array of bytes to hold bit data and corresponding array length.
+ *
+ *  The bits in the struct are assembled in as an array of bytes with eight bits per byte. The bits are
+ *  arranged with the LSB in first (right most) position of the first array element.
+ */
+typedef struct
+{
+    int n;                             ///< Number of bytes in the array
+    char *bits;                        ///< Aray of bytes holding bits
+}
+psBitSet;
+
+/*****************************************************************************/
+/* FUNCTION PROTOTYPES                                                       */
+/*****************************************************************************/
+
+/** Allocate a psBitSet.
+ *
+ *  Create a psBitSet with the number of bits specified by the user. All bits are set to zero upon
+ *  allocation.
+ *
+ *  @return  psBitSet* : Pointer to struct containing array of bits and size of array.
+ */
+
+/*@null@*/
+psBitSet* psBitSetAlloc(
+    int n                              ///< Number of bits in psBitSet array
+);
+
+/** Set a bit.
+ *
+ *  Sets a bit at a given bit location. The bit is set based on a zero index with the
+ *  first bit set in the zero bit slot of the zero element of the byte array. As an example, setting bit 3 in
+ *  an array with two elements would result in an psBitSet that looks like 00000000 00001000.
+ *
+ *  @return  psBitSet* : Pointer to struct containing psBitSet.
+ */
+psBitSet* psBitSetSet(
+    /* @returned@ */
+    psBitSet* restrict inMask,         ///< Pointer to psBitSet to be set.
+    int bit                            ///< Bit to be set.
+);
+
+/** Clear a bit.
+ *
+ *  Clear a bit at a given bit location. The bit is cleared based on a zero 
+ *  index with the first bit set in the zero bit slot of the zero element of 
+ *  the byte array. 
+ *
+ *  @return  psBitSet* : Pointer to struct containing psBitSet.
+ */
+psBitSet* psBitSetClear(
+    /* @returned@ */
+    psBitSet* restrict inMask,         ///< Pointer to psBitSet to be cleared.
+    int bit                            ///< Bit to be cleared.
+);
+
+/** Test the value of a bit.
+ *
+ *  Prints the value of a bit at a given bit location, either one or zero. The resulting bit is based on a
+ *  zero index format with the first bit set in the zero bit slot of the zero element of the byte array
+ *  As an example, testing bit 3 in a psBitSet with two bytes that looks like 00000000 00001000 would return a
+ *  value of one, since that is the value that was set.
+ *
+ *  @return  int: Value of bit, either one or zero.
+ */
+
+bool psBitSetTest(
+    const psBitSet* restrict inMask,   ///< Pointer psBitSet to be tested.
+    int bit                            ///< Bit to be tested.
+);
+
+/** Perform a binary operation on two psBitSets
+ *
+ *  Perform an AND, OR, or XOR on two psBitSets. If the BitMasks are not the same size, the operation will not
+ *  be performed and an error message will be logged.
+ *
+ *  @return  psBitSet* : Pointer to struct containing result of binary operation.
+ */
+psBitSet* psBitSetOp(
+    /* @returned@ */
+    psBitSet* restrict outMask,        ///< Resulting psBitSet from binary operation
+    const psBitSet* restrict inMask1,  ///< First psBitSet on which to operate
+    char *operator,                    ///< Bit operation
+    const psBitSet* restrict inMask2   ///< First psBitSet on which to operate
+);
+
+/** Perform a not operation on a psBitSet
+ *
+ *  Toggles bits in a psBitset. All zero bits are set to one and all one bits are set to zero.
+ *
+ *  @return  psBitSet* : Pointer to struct containing result of operation.
+ */
+
+psBitSet* psBitSetNot(
+    psBitSet* outBitSet,               ///< Resulting psBitSet from operation
+    const psBitSet* restrict inBitSet  ///< Input psBitSet
+);
+
+/** Convert the psBitSet to a string of ones and zeros.
+ *
+ *  Converts the contents of a psBitSet to a string representation of its binary form of ones and zeros. The
+ *  LSB is the right-most chracter. Each set of eight characters represents one byte.
+ *
+ *  @return  char*: Pointer to character array containing string data.
+ */
+
+char *psBitSetToString(
+    const psBitSet* restrict inMask    ///< psBitSet to convert */
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/types/psHash.c
===================================================================
--- /branches/rel3/psLib/src/types/psHash.c	(revision 2163)
+++ /branches/rel3/psLib/src/types/psHash.c	(revision 2163)
@@ -0,0 +1,437 @@
+
+/** @file  psHash.c
+*
+*  @brief Contains support for basic hashing functions.
+*
+*  This file will hold the functions for defining a hash table with arbitrary
+*  data types, allocating/deallocating that hash table, adding and removing
+*  data from that hash table, and listing all keys defined in the hash table.
+*
+*  @author Robert Lupton, Princeton University
+*  @author George Gusciora, MHPCC
+*
+*  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-09-21 23:17:53 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include "psHash.h"
+#include "psMemory.h"
+#include "psString.h"
+#include "psTrace.h"
+#include "psError.h"
+#include "psAbort.h"
+
+#include "psCollectionsErrors.h"
+
+static psHashBucket* hashBucketAlloc(const char *key, void *data, psHashBucket* next);
+static void hashBucketFree(psHashBucket* bucket);
+static void *doHashWork(psHash* table, const char *key, void *data, bool remove
+                           );
+static void hashFree(psHash* table);
+
+/******************************************************************************
+psHashKeyList(table): this function creates a linked list with an entry in
+that list for every key in the hash table.
+Inputs:
+    table: a hash table
+Return;
+    The linked list
+ *****************************************************************************/
+psList* psHashKeyList(psHash* table)
+{
+    int i = 0;                  // Loop index variable
+    psList* myLinkList = NULL;  // The output data structure
+    psHashBucket* ptr = NULL;   // Used to step thru linked list.
+
+    if (table == NULL) {
+        return NULL;
+    }
+    // Create the linked list
+    myLinkList = psListAlloc(NULL);
+
+    // Loop through every bucket in the hash table.  If that bucket is not
+    // NULL, then add the bucket's key to the linked list.
+    for (i = 0; i < table->nbucket; i++) {
+        if (table->buckets[i] != NULL) {
+            // Since a bucket contains a linked list of keys/data, we must
+            // step trough each key in that linked list:
+
+            ptr = table->buckets[i];
+            while (ptr != NULL) {
+                psListAdd(myLinkList, PS_LIST_HEAD, ptr->key);
+                ptr = ptr->next;
+            }
+        }
+    }
+
+    // Return the linked list
+    return (myLinkList);
+}
+
+/******************************************************************************
+hashBucketAlloc(key, data, next): This procedure creates a new hash bucket
+with the specified key, data, and next.
+Inputs:
+    key:  the new bucket's key pointer
+    data: the new bucket's data pointer
+    next: the new bucket's key pointer
+Return:
+    the new hash bucket.
+ *****************************************************************************/
+static psHashBucket* hashBucketAlloc(const char *key,
+                                     void *data,
+                                     psHashBucket* next)
+{
+    // Allocate memory for the new hash bucket.
+    psHashBucket* bucket = psAlloc(sizeof(psHashBucket));
+
+    p_psMemSetDeallocator(bucket, (psFreeFcn) hashBucketFree);
+
+    // Initialize the bucket.
+    bucket->key = psStringCopy(key);
+
+    if (data == NULL) {
+        // NOTE: Should we flag a warning message?
+        bucket->data = NULL;
+    } else {
+        bucket->data = psMemIncrRefCounter(data);
+    }
+
+    bucket->next = next;
+
+    return bucket;
+}
+
+/******************************************************************************
+hashBucketFree(bucket): This procedure deallocates the specified
+hash bucket.
+Inputs:
+    bucket: the hash bucket to be freed.
+Return:
+    NONE
+ *****************************************************************************/
+static void hashBucketFree(psHashBucket* bucket)
+{
+    if (bucket == NULL) {
+        return;
+    }
+
+    psFree(bucket->key);
+
+    psFree(bucket->data);
+}
+
+/******************************************************************************
+psHashAlloc(nbucket): this procedure creates a new hash table with the
+specified number of buckets.
+Inputs:
+    nbucket: initial number of buckets
+Return:
+    The new hash table.
+ *****************************************************************************/
+psHash* psHashAlloc(int nbucket)        // initial number of buckets
+{
+    int i = 0;                  // loop index variable
+
+    // Create the new hash table.
+    psHash* table = psAlloc(sizeof(psHash));
+
+    p_psMemSetDeallocator(table, (psFreeFcn) hashFree);
+
+    // Allocate memory for the buckets.
+    table->buckets = psAlloc(nbucket * sizeof(psHashBucket* ));
+    table->nbucket = nbucket;
+
+    psTrace("utils.hash", 1, "Creating %d-element hash table\n", nbucket);
+
+    // Initialize all buckets to NULL.
+    for (i = 0; i < nbucket; i++)
+    {
+        table->buckets[i] = NULL;
+    }
+
+    // Return the new hash table.
+    return table;
+}
+
+/******************************************************************************
+psHashFree(table, itemFree): This procedure deallocates the specified hash
+table.  It loops through each bucket, and calls hashBucketFree() on that
+bucket.
+ 
+Inputs:
+    table: a hash table
+Return:
+    NONE
+ *****************************************************************************/
+static void hashFree(psHash* table)
+{
+    int i = 0;                  // Loop index variable.
+
+    if (table == NULL) {
+        return;
+    }
+    // Loop through each bucket in the hash table.  If that bucket is not
+    // NULL, then free the bucket via a function call to hashBucketFree();
+    for (i = 0; i < table->nbucket; i++) {
+
+        // A bucket is composed of a linked list of buckets.
+        while (table->buckets[i] != NULL) {
+            psHashBucket* bucket = table->buckets[i];
+            table->buckets[i] = bucket->next;
+            psFree(bucket);
+        }
+    }
+
+    // Free the bucket structure, then the hash table.
+    psFree(table->buckets);
+}
+
+/******************************************************************************
+doHashWork(table, key, data, remove): This is an internal
+procedure which does the bulk of the work in using the hash table.  Depending
+upon the input parameters, it will either insert a new key/data into the hash
+table, retrieve the data for a specified key, or remove a key/data item.  If
+we try to insert a key that already exists in the hash table, then we deallocate
+the existing data/key item.
+Inputs:
+    table: a hash table
+    key: the key to insert, retrieve, or remove.  Must not be NULL.
+    data: the data to insert, if not NULL
+    remove: set to non-zero if the key/data should be removed from the table.
+Return:
+    NONE
+ 
+NOTE: consider removing this private function and simply putting the code
+into the psHashInsert(), psHashLookup(), and psHashRemove().  Why?  Because
+there is little common code between those functions.
+  *****************************************************************************/
+static void *doHashWork(psHash* table,
+                        const char *key,
+                        void *data, bool remove
+                           )
+{
+    long int hash = 1;          // This will contain an integer value
+
+    // "hashed" from the key.
+    char *tmpchar = NULL;       // Used in computing the hash function.
+    psHashBucket* ptr = NULL;   // Used to retrieve the hash bucket.
+    psHashBucket* optr = NULL;  // "original pointer": used to step
+
+    // thru the linked list for a bucket.
+
+    // The following condition should never be true, since this is a private
+    // function, but I'm checking it anyway since future coders might change
+    // the way this procedure is called.
+    if ((table == NULL) || (key == NULL)) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "doHashWork",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psHash_KEY_NULL);
+        return NULL;
+    }
+    // NOTE: This is the originally supplied hash function.
+    // for (int i = 0, len = strlen(key); i < len; i++) {
+    // hash = (hash << 1) ^ key[i];
+    // }
+    // hash &= (table->nbucket - 1);
+
+    // This hash algorithm is from Sedgewick.  NOTE: must reread to ensure that
+    // the size of the hash table is not required to be a prime number.
+    tmpchar = (char *)key;
+    for (hash = 0; *tmpchar != '\0'; tmpchar++) {
+        hash = (64 * hash + *tmpchar) % (table->nbucket);
+    }
+
+    // NOTE: This should not be necessary, but for now, I'm checking bounds
+    // anyway.
+    if ((hash < 0) || (hash >= table->nbucket)) {
+        psAbort(__func__, "Internal hash function out of range (%d)", hash);
+    }
+    // ptr will have the correct hash bucket.
+    ptr = table->buckets[hash];
+
+    // We know the correct hash bucket, now we need to know what to do.
+    // If the data parameter is NULL, then, by definition, this is a retrieve
+    // or a remove operation on the hash table.
+
+    if (data == NULL) {
+        if (remove
+           ) {
+            // We search through the linked list for this bucket in
+            // the hash table and look for an entry for this key.
+
+            optr = ptr;
+            while (ptr != NULL) {
+                // Determine if this entry holds the correct key.
+                if (strcmp(key, ptr->key) == 0) {
+                    // The following lines of code are fairly standard ways
+                    // of removing an item from a single-linked list.
+
+                    void *data = ptr->data;
+
+                    optr->next = ptr->next;
+                    if (ptr == table->buckets[hash]) {
+                        table->buckets[hash] = ptr->next;
+                    }
+                    psFree(ptr);
+
+                    // By definition, the data associated with that key
+                    // must be returned, not freed.
+                    return data;
+                }
+                optr = ptr;
+                ptr = ptr->next;
+            }
+            return NULL;                   // not in hash
+        }
+        else {
+            // If we get here, then a retrieve operation is requested.  So,
+            // we step trough the linked list at this bucket, and return the
+            // data once we find it, or return NULL if we don't.
+            while (ptr != NULL) {
+                if (strcmp(key, ptr->key) == 0) {
+                    return ptr->data;
+                }
+                ptr = ptr->next;
+            }
+            return NULL;                   // not in hash
+        }
+    } else {
+        // We get here if this procedure was called with non-NULL data.
+        // Therefore, we should insert that data into the hash table.
+        // First, we search through the linked list for this bucket in
+        // the hash table and look for a duplicate entry for this key.
+
+        while (ptr != NULL) {
+            if (strcmp(key, ptr->key) == 0) {
+                // We have found this key in the hash table.
+
+                psTrace("utils.hash.insert", 3, "Replacing data for %s\n", key);
+
+                // NOTE: I have changed this behavior from the originally
+                // supplied code.  Formerly, if itemFree was NULL, then
+                // the new data was not inserted into the hash table.
+
+                psFree(ptr->data);
+
+                ptr->data = psMemIncrRefCounter(data);
+                return data;
+            }
+            ptr = ptr->next;
+        }
+        // We did not found key in the linked list for this bucket of the hash
+        // table.  So, we insert this data at the head of that linked list.
+
+        table->buckets[hash] = hashBucketAlloc(key, data, table->buckets[hash]);
+        return data;
+    }
+}
+
+/******************************************************************************
+psHashInsert(table, key, data, itemFree): this procedure, which is part of
+the public API, inserts a new key/data pair into the hash table.
+Inputs:
+    table: a hash table
+    key: the key to use
+    data: the data to insert.
+    itemFree: a function pointer
+Return:
+    boolean value defining success or failure
+ *****************************************************************************/
+bool psHashAdd(psHash* table,
+               const char *key,
+               void *data)
+{
+    if (table == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psHashAdd",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psHash_KEY_NULL);
+        return false;
+    }
+    if (key == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psHashAdd",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psHash_TABLE_NULL);
+        return false;
+    }
+    if (data == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psHashAdd",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psHash_DATA_NULL);
+    }
+
+    return (doHashWork(table, key, data, 0) != NULL);
+}
+
+/******************************************************************************
+psHashLookup(table, key): this procedure, which is part of the public API,
+looks up the specified key in the hash table and returns the data associated
+with that key.
+ 
+Inputs:
+    table: a hash table
+    key: the key to use
+Return:
+    The data associated with that key.
+ *****************************************************************************/
+void *psHashLookup(psHash* table,      // table to lookup key in
+                   const char *key)     // key to lookup
+{
+    if (table == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psHashLookup",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psHash_KEY_NULL);
+        return NULL;
+    }
+    if (key == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psHashLookup",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psHash_TABLE_NULL);
+        return NULL;
+    }
+
+    return doHashWork(table, key, NULL, 0);
+}
+
+/******************************************************************************
+psHashRemove(table, key, itemFree): this procedure, which is part of the
+public API, removes the specified key from the hash table.
+Inputs:
+    table: a hash table
+    key: the key to remove
+    itemFree: a function pointer
+Return:
+    boolean value defining success or failure
+ *****************************************************************************/
+bool psHashRemove(psHash* table,
+                  const char *key)
+{
+    void *data = NULL;
+    bool retVal = false;
+
+    if (table == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psHashRemove",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psHash_TABLE_NULL);
+        return false;
+    }
+    if (key == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "psHashRemove",
+                   PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_psHash_KEY_NULL);
+        return false;
+    }
+
+    data = doHashWork(table, key, NULL, 1);
+    if (data != NULL) {
+        retVal = true;
+    } else {
+        retVal = false;
+    }
+    return retVal;
+}
Index: /branches/rel3/psLib/src/types/psHash.h
===================================================================
--- /branches/rel3/psLib/src/types/psHash.h	(revision 2163)
+++ /branches/rel3/psLib/src/types/psHash.h	(revision 2163)
@@ -0,0 +1,73 @@
+
+/** @file  psHash.h
+ *  @brief Contains support for basic hashing functions.
+ *  @ingroup HashTable
+ *
+ *  This file will hold the prototypes for defining a hash table with arbitrary
+ *  data types, allocating/deallocating that has table, adding and removing
+ *  data from that hash table, and listing all keys defined in the hash table.
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author George Gusciora, MHPCC
+ *   
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-08-09 23:40:55 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+#if !defined(PS_HASH_H)
+#define PS_HASH_H
+
+/** \addtogroup HashTable
+ *  \{
+ */
+#include<stdbool.h>
+
+#include "psList.h"
+
+/** A bucket that holds an item of data. */
+typedef struct psHashBucket
+{
+    char *key;                  ///< key for this item of data
+    void *data;                 ///< the data itself
+    struct psHashBucket* next;  ///< list of other possible keys
+}
+psHashBucket;
+
+//typedef struct HashTable psHash; ///< Opaque type for a hash table
+
+/** The hash-table itself. */
+typedef struct psHash
+{
+    int nbucket;                ///< Number of buckets in hash table.
+    psHashBucket* *buckets;     ///< The bucket data.
+}
+psHash;
+
+/// Allocate hash buckets in table.
+psHash* psHashAlloc(int nbucket ///< The number of buckets to allocate.
+                   );
+
+/// Insert entry into table.
+bool psHashAdd(psHash* table,  ///< table to insert in
+               const char *key, ///< key to use
+               void *data       ///< data to insert
+              );
+
+/// Lookup key in table.
+void *psHashLookup(psHash* table,      ///< table to lookup key in
+                   const char *key      ///< key to lookup
+                  );
+
+/// Remove key from table.
+bool psHashRemove(psHash* table,       ///< table to lookup key in
+                  const char *key       ///< key to lookup
+                 );
+
+/// List all keys in table.
+psList* psHashKeyList(psHash* table    ///< table to list keys from.
+                     );
+
+/* \} */// End of DataGroup Functions
+
+#endif
Index: /branches/rel3/psLib/src/types/psList.c
===================================================================
--- /branches/rel3/psLib/src/types/psList.c	(revision 2163)
+++ /branches/rel3/psLib/src/types/psList.c	(revision 2163)
@@ -0,0 +1,475 @@
+/** @file psList.c
+ *  @brief Support for doubly linked lists
+ *  @ingroup LinkedList
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.19 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-14 20:01:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <pthread.h>                       // we need a mutex to make this stuff thread safe.
+
+#include "psError.h"
+#include "psAbort.h"
+#include "psMemory.h"
+#include "psList.h"
+#include "psTrace.h"
+#include "psLogMsg.h"
+
+#include "psCollectionsErrors.h"
+
+#define ITER_INIT_HEAD ((void *)1)         // next iteration should return head
+#define ITER_INIT_TAIL ((void *)2)         // next iteration should return tail
+
+// private functions.
+static psListElem* listGetIterator(psList* list);
+static int listGetIteratorIndex(psList* list);
+static void listSetIterator(psList* list, int where, bool lockList);
+static void listFree(psList* list);
+
+psList* psListAlloc(void *data)
+{
+    psList* list = psAlloc(sizeof(psList));
+
+    p_psMemSetDeallocator(list, (psFreeFcn) listFree);
+
+    list->size = 0;
+    list->head = list->tail = NULL;
+    list->iter = ITER_INIT_HEAD;
+    list->iterIndex = PS_LIST_HEAD;
+
+    pthread_mutex_init(&(list->lock), NULL)
+    ;
+
+    if (data != NULL) {
+        psListAdd(list, PS_LIST_TAIL, data);
+    }
+
+    return list;
+}
+
+static void listFree(psList* list)
+{
+    if (list == NULL) {
+        return;
+    }
+
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    for (psListElem* ptr = list->head; ptr != NULL;) {
+        psListElem* next = ptr->next;
+
+        psFree(ptr->data);
+        psFree(ptr);
+
+        ptr = next;
+    }
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    pthread_mutex_destroy(&list->lock)
+    ;
+
+}
+
+bool psListAdd(psList* list, int location, void *data)
+{
+    psListElem* position;
+    psListElem* elem;
+    int cursorIndex = 0;
+
+    if (list == NULL) {
+        return false;
+    }
+
+    if (data == NULL) {
+        return false;
+    }
+
+    if (location <= PS_LIST_UNKNOWN) {
+        // / XXX What is the better way to communicate this failure to the caller?
+        psLogMsg(__func__, PS_LOG_WARN, "The given insert location (%i) for psListAdd is invalid.", location);
+        return false;
+    }
+
+    elem = psAlloc(sizeof(psListElem));
+
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    if (location > 0 && location > list->size) {
+        psLogMsg(__func__, PS_LOG_WARN,
+                 "Invalid index %d (only %d elements in psList); assuming tail.", location, list->size);
+        location = PS_LIST_TAIL;
+    }
+
+    if (location == PS_LIST_TAIL || list->size == 0) {
+        // insert the element at the end of the list
+        elem->prev = list->tail;
+        elem->next = NULL;
+
+        if (list->tail != NULL) {
+            list->tail->next = elem;
+        }
+
+        if (list->head == NULL) {
+            list->head = elem;
+        }
+        list->tail = elem;
+
+        list->size++;
+        list->iter = elem;
+        list->iterIndex = list->size - 1;
+    } else {
+        // move ourselves to the given position
+        listSetIterator(list, location, false);
+        position = listGetIterator(list);
+        cursorIndex = listGetIteratorIndex(list);
+
+        if (position == NULL) {
+            psError(__func__, "%s failed to move cursor to specified location (%d)", __func__, location);
+            position = list->head;         // since we no list->size != 0, this must be non-NULL
+        }
+        // insert our new element in front of the given position
+        elem->prev = position->prev;
+        elem->next = position;
+        position->prev = elem;
+
+        if (elem->prev == NULL) {          // must be front of list
+            list->head = elem;
+        } else {
+            elem->prev->next = elem;
+        }
+
+        list->size++;
+        list->iter = elem;
+        list->iterIndex = cursorIndex;
+    }
+
+    elem->data = psMemIncrRefCounter(data);
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    return true;
+}
+
+
+/*
+ * Remove an element from a list
+ */
+bool psListRemove(psList* list, int location, void *data)
+{
+    psListElem* elem = NULL;    // element to remove
+    int cursorIndex = 0;
+
+    if (list == NULL) {
+        psError(__func__, "list parameter found to be NULL in %s", __func__);
+        return false;
+    }
+    // get exclusive access to list so that other threads will not get in the way.
+    pthread_mutex_lock(&list->lock)
+    ;
+
+    if (location == PS_LIST_UNKNOWN) {
+        // search list for the data item.
+
+        int i = 0;              // index
+
+        for (psListElem* ptr = list->head; ptr != NULL; ptr = ptr->next) {
+            if (ptr->data == data) {
+                location = i;
+                break;
+            }
+            i++;
+        }
+
+        if (location == PS_LIST_UNKNOWN) {
+            psError(__func__, "Failed to find item in given psList.");
+            pthread_mutex_unlock(&list->lock)
+            ;
+            return false;
+        }
+    }
+    // position the list's cursor to the desired location
+    listSetIterator(list, location, false);
+    elem = listGetIterator(list);
+    cursorIndex = listGetIteratorIndex(list);
+
+    if (elem == NULL) {
+        psError(__func__, "Couldn't position to given index (%d) to remove element from list.", location);
+        pthread_mutex_unlock(&list->lock)
+        ;
+        return false;
+    }
+
+    list->size--;
+
+    if (elem->prev == NULL) {              // head of list?
+        list->head = elem->next;
+    } else {
+        elem->prev->next = elem->next;
+    }
+
+    if (elem->next == NULL) {              // tail of list?
+        list->tail = elem->prev;
+
+        // removed tail, so iter should be the last element of list to keep it valid
+        if (list->size > 0) {
+            list->iter = list->tail;
+            list->iterIndex = list->size - 1;
+        } else {
+            list->iter = ITER_INIT_TAIL;
+        }
+    } else {
+        elem->next->prev = elem->prev;
+        list->iter = elem->next;
+        list->iterIndex = cursorIndex;
+    }
+
+    pthread_mutex_unlock(&list->lock)
+    ;
+
+    // OK, delete list element and its data
+    psFree(elem->data);
+    psFree(elem);
+
+    return true;
+}
+
+void psListSetIterator(psList* list, int where)
+{
+    listSetIterator(list, where, true);
+}
+
+static void listSetIterator(psList* list, int where, bool lockList)
+{
+    psListElem* cursor;
+    int position;
+
+    if (list == NULL) {
+        psError(__func__, "Unexpected null pointer for psList parameter (%s:%d).", __FILE__, __LINE__);
+        return;
+    }
+
+    if (where == PS_LIST_CURRENT) {
+        return;
+    }
+
+    if (lockList) {
+        pthread_mutex_lock(&list->lock)
+        ;
+        // don't want the list changing on us while we move about
+    }
+
+    if (where >= (int)list->size) {
+        list->iter = NULL;
+        if (lockList) {
+            pthread_mutex_unlock(&list->lock)
+            ;
+        }
+        return;
+    }
+
+    switch (where) {
+    case PS_LIST_HEAD:
+        list->iter = ITER_INIT_HEAD;
+        break;
+
+    case PS_LIST_TAIL:
+        list->iter = ITER_INIT_TAIL;
+        break;
+
+    case PS_LIST_PREVIOUS:
+        cursor = listGetIterator(list);
+        position = listGetIteratorIndex(list);
+
+        if (cursor != NULL) {
+            list->iter = cursor->prev;
+            list->iterIndex = position - 1;
+        }
+        break;
+
+    case PS_LIST_NEXT:
+        cursor = listGetIterator(list);
+        position = listGetIteratorIndex(list);
+
+        if (cursor != NULL) {
+            list->iter = cursor->next;
+            list->iterIndex = position + 1;
+        }
+        break;
+
+    case PS_LIST_CURRENT:
+        break;
+
+    default:
+        if (where <= PS_LIST_HEAD) {   // bascially same as PS_LIST_UNKNOWN above
+            psError(__func__, "Can't move to an unknown position.  Not moving the iterator position.");
+        } else {
+            cursor = listGetIterator(list);
+            if (cursor == NULL) {      // reset the iterator if it is invalid
+                list->iter = ITER_INIT_HEAD;
+                list->iterIndex = 0;
+            }
+
+            int position = listGetIteratorIndex(list);
+
+            if (where < position) {
+                int diff = position - where;
+
+                for (int count = 0; count < diff; count++) {
+                    listSetIterator(list, PS_LIST_PREVIOUS, false);
+                }
+            } else {
+                int diff = where - position;
+
+                for (int count = 0; count < diff; count++) {
+                    listSetIterator(list, PS_LIST_NEXT, false);
+                }
+            }
+        }
+        break;
+    }
+
+    if (lockList) {
+        pthread_mutex_unlock(&list->lock)
+        ;
+    }
+}
+
+psListElem* listGetIterator(psList* list)
+{
+    if (list == NULL) {
+        return NULL;
+    }
+
+    if (list->iter == ITER_INIT_HEAD) {
+        return list->head;
+    } else if (list->iter == ITER_INIT_TAIL) {
+        return list->tail;
+    } else {
+        return list->iter;
+    }
+}
+
+int listGetIteratorIndex(psList* list)
+{
+    if (list->iter == ITER_INIT_HEAD) {
+        return 0;
+    } else if (list->iter == ITER_INIT_TAIL) {
+        return list->size - 1;
+    } else {
+        return list->iterIndex;
+    }
+}
+
+void *psListGet(psList* list, int location)
+{
+    psListElem* element;
+
+    psListSetIterator(list, location);
+    element = listGetIterator(list);
+
+    if (element == NULL) {
+        return NULL;
+    } else {
+        return element->data;
+    }
+}
+
+/*
+ * and now return the previous/next element of the list
+ */
+void *psListGetNext(psList* list)
+{
+    return psListGet(list, PS_LIST_NEXT);
+}
+
+void *psListGetPrevious(psList* list)
+{
+    return psListGet(list, PS_LIST_PREVIOUS);
+}
+
+void *psListGetCurrent(psList* list)
+{
+    return psListGet(list, PS_LIST_CURRENT);
+}
+
+/*
+ * Convert a psList to/from a psVoidPtrArray
+ */
+psArray* psListToArray(psList* restrict list)
+{
+    psListElem* ptr;
+    unsigned int n;
+    psArray* restrict arr;
+
+    if (list == NULL) {
+        return NULL;
+    }
+
+    if (list->size > 0) {
+        arr = psArrayAlloc(list->size);
+    } else {
+        arr = psArrayAlloc(1);
+    }
+
+    arr->n = list->size;
+
+    ptr = list->head;
+    n = list->size;
+    for (int i = 0; i < n; i++) {
+        arr->data[i] = psMemIncrRefCounter(ptr->data);
+        ptr = ptr->next;
+    }
+
+    return arr;
+}
+
+psList* psArrayToList(psArray* arr)
+{
+    unsigned int n;
+    psList* list;               // list of elements
+
+    if (arr == NULL) {
+        return NULL;
+    }
+
+    list = psListAlloc(NULL);
+    n = arr->n;
+    for (int i = 0; i < n; i++) {
+        psListAdd(list, PS_LIST_TAIL, arr->data[i]);
+    }
+
+    return list;
+}
+
+psList* psListSort(psList* list, psComparePtrFcn compare)
+{
+    psArray* arr;
+
+    if (list == NULL) {
+        return NULL;
+    }
+    // convert to indexable vector for use by qsort.
+    arr = psListToArray(list);
+    psFree(list);
+
+    arr = psArraySort(arr, compare);
+
+    // convert back to linked list
+    list = psArrayToList(arr);
+    psFree(arr);
+
+    return list;
+}
Index: /branches/rel3/psLib/src/types/psList.h
===================================================================
--- /branches/rel3/psLib/src/types/psList.h	(revision 2163)
+++ /branches/rel3/psLib/src/types/psList.h	(revision 2163)
@@ -0,0 +1,192 @@
+#if !defined(PS_LIST_H)
+#define PS_LIST_H
+
+/** @file psList.h
+ *  @brief Support for doubly linked lists
+ *
+ *  @author Robert Lupton, Princeton University
+ *  @author Robert Daniel DeSonia, MHPCC
+ *
+ *  @ingroup LinkedList
+ *
+ *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-09 02:23:27 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <pthread.h>                   // we need a mutex to make this stuff thread safe.
+#include <stdbool.h>                   // we use the bool type.
+
+#include "psCompare.h"
+#include "psArray.h"
+
+/** @addtogroup LinkedList
+ *  @{
+ */
+
+/** Special values of index into list
+ *
+ *  This list of possible list position values should be contiguous non-positive values ending with
+ *  PS_LIST_UNKNOWN.  Any value less-than-or-equal-to PS_LIST_UNKNOWN is considered a undefined position.
+ *
+ */
+enum {
+    PS_LIST_HEAD = 0,                  ///< at head
+    PS_LIST_TAIL = -1,                 ///< at tail
+    PS_LIST_PREVIOUS = -2,             ///< previous element
+    PS_LIST_CURRENT = -3,              ///< current element
+    PS_LIST_NEXT = -4,                 ///< next element
+    PS_LIST_UNKNOWN = -5               ///< unknown position (should be last in enum list)
+};
+
+/** Doubly-linked list element */
+typedef struct psListElem
+{
+    struct psListElem* prev;           ///< previous link in list
+    struct psListElem* next;           ///< next link in list
+    void *data;                        ///< real data item
+}
+psListElem;
+
+/** The psList Linked list structure.  User should not allocate this struct
+ *  directly; rather the psListAlloc should be used.
+ *
+ *  @see psListAlloc, psListFree
+ */
+typedef struct
+{
+    unsigned int size;                 ///< number of elements on list
+    psListElem* head;                  ///< first element on list (may be NULL)
+    psListElem* tail;                  ///< last element on list (may be NULL)
+    psListElem* iter;                  ///< iteration cursor
+    unsigned int iterIndex;            ///< the numeric position of the iteration cursor in the list
+    pthread_mutex_t lock;              ///< mutex to lock a node during changes
+}
+psList;
+
+/** Creates a psList linked list object.
+ *
+ *  @return psList* A new psList object.
+ */
+psList* psListAlloc(
+    void *data
+    ///< initial data item; may be NULL if no an empty psList is desired
+)
+;
+
+/** Adds an element to a psList at position given.
+ *
+ *  @return psList* The psList with added data item.  If list parameter is
+ *                      NULL, the return value will also be NULL.
+ */
+bool psListAdd(
+    psList* restrict list,             ///< list to add to (if NULL, nothing is done)
+    int location,                      ///< index, PS_LIST_HEAD, PS_LIST_TAIL, or numbered location.
+    void *data                         ///< data item to add.  If NULL, list is not modified.
+);
+
+/** Remove an item from a list.  If location parameter is PS_LIST_UNKNOWN,
+ *
+ *  @return bool        TRUE if element is successfully removed, otherwise FALSE.
+ */
+bool psListRemove(
+    psList* restrict list,
+    ///< list to remove element from
+    int location,
+    ///< index of item, or PS_LIST_UNKNOWN, PS_LIST_NEXT, PS_LIST_PREV, or numbered location.
+    void *data
+    ///< if location is PS_LIST_UNKNOWN, data item to find and remove, otherwise this is ignored.
+);
+
+/** Retrieve an item from a list.
+ *
+ *  @return void*       the item corresponding to the location parameter.  If
+ *                      location is invalid (e.g., a numbered index greater
+ *                      than the list size or if the list is empty), a
+ *                      NULL is returned.
+ */
+void *psListGet(
+    psList* restrict list,             ///< list to retrieve element from
+    int location                       ///< index number, or PS_LIST_NEXT, PS_LIST_PREV, PS_LIST_UNKNOWN
+);
+
+/** Set the iterator of the list to a given position.  If location is invalid the
+ *  iterator position is not changed.
+ *
+ */
+void psListSetIterator(
+    psList* restrict list,             ///< list to retrieve element from
+    int location                       ///< index number, PS_LIST_HEAD, or PS_LIST_TAIL
+);
+
+/** Get next element relative to the iterator.  This also moves the iterator to
+ *  the next list position.
+ *
+ *  @return void*       the data item next on the list or NULL if the iterator
+ *                      is already pointing to the last element or the list
+ *                      parameter was NULL.
+ */
+void *psListGetNext(
+    psList* restrict list              ///< list to retrieve element from
+);
+
+/** Get current element according to the psList's iterator cursor.  This does
+ *  not move the iterator location.
+ *
+ *  @return void*       the data item cooresponding to current iterator
+ *                      cursor position of the list, or NULL if either the
+ *                      iterator is not valid or list parameter was NULL.
+ */
+void *psListGetCurrent(
+    psList* restrict list              ///< list to retrieve element from
+);
+
+/** Get previous element relative to list's iterator. This also moves the
+ *  iterator to the previous list position.
+ *
+ *  @return void*       the data item previous on the list or NULL if the iterator
+ *                      is already pointing to the first element or the list
+ *                      parameter was NULL.
+ */
+void *psListGetPrevious(
+    psList* restrict list              ///< list to retrieve element from
+);
+
+/** Convert a linked list to an array
+ *
+ *  @return psArray* A new psArray populated with elements from the list,
+ *                      or NULL if the given dlist parameter is NULL.
+ */
+psArray* psListToArray(
+    psList* dlist                      ///< List to convert
+);
+
+/** Convert array to a doubly-linked list
+ *
+ *  @return psList* A new psList populated with elements formt the psArray,
+ *                      or NULL is the given arr parameter is NULL.
+ */
+psList* psArrayToList(
+    psArray* arr                       ///< vector to convert
+);
+
+/** Sort a list via a comparison function.
+ *
+ *  The comparison function must return an integer less than, equal to, or 
+ *  greater than zero if the first argument is considered to be respectively 
+ *  less than, equal to, or greater than the second. 
+ *
+ *  If two members compare as equal, their order in the sorted array is 
+ *  undefined.
+ *
+ *  @return psList*     Sorted list.
+ */
+psList* psListSort(
+    psList* list,                      ///< the list to sort
+    psComparePtrFcn compare            ///< the comparison function
+);
+
+/// @} End of DataGroup Functions
+
+#endif
Index: /branches/rel3/psLib/src/types/psMetadata.c
===================================================================
--- /branches/rel3/psLib/src/types/psMetadata.c	(revision 2163)
+++ /branches/rel3/psLib/src/types/psMetadata.c	(revision 2163)
@@ -0,0 +1,589 @@
+
+/** @file  psMetadata.c
+*
+*
+*  @brief Contains metadata structures, enumerations and functions prototypes.
+*
+*  This file defines metadata item, metadata type, metadata flags, metadata containers, and function
+*  prototypes necessary creating psLib metadata APIs
+*
+*  @ingroup Metadata
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.34 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-09 03:05:53 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+/******************************************************************************/
+/*  INCLUDE FILES                                                             */
+/******************************************************************************/
+#include<stdio.h>
+#include<stdarg.h>
+#include<string.h>
+
+#include "fitsio.h"
+#include "psType.h"
+#include "psMemory.h"
+#include "psError.h"
+#include "psAbort.h"
+#include "psList.h"
+#include "psHash.h"
+#include "psVector.h"
+#include "psMetadata.h"
+#include "psString.h"
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Maximum size of a string */
+#define MAX_STRING_LENGTH 1024
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+static int metadataId = 0;
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+static void metadataItemFree(psMetadataItem* metadataItem)
+{
+    psMetadataType type;
+
+    type = metadataItem->type;
+
+    if (metadataItem == NULL) {
+        return;
+    }
+
+    psFree(metadataItem->name);
+    psFree(metadataItem->comment);
+    psFree(metadataItem->items);
+
+    if (type == PS_META_STR || type == PS_META_VEC || type == PS_META_IMG || type == PS_META_JPEG ||
+            type == PS_META_PNG || type == PS_META_ASTROM || type == PS_META_UNKNOWN) {
+        psFree(metadataItem->data.V);
+    }
+}
+
+static void metadataFree(psMetadata* metadata)
+{
+    if (metadata == NULL) {
+        return;
+    }
+    psFree(metadata->list);
+    psFree(metadata->table);
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+psMetadataItem* psMetadataItemAlloc(const char *name, psMetadataType type, const char *comment, ...)
+{
+    va_list argPtr;
+    psMetadataItem* metadataItem = NULL;
+
+    // Get the variable list parameters to pass to allocation function
+    va_start(argPtr, comment);
+
+    // Call metadata item allocation
+    metadataItem = psMetadataItemAllocV(name, type, comment, argPtr);
+
+    // Clean up stack after variable arguement has been used
+    va_end(argPtr);
+
+    return metadataItem;
+}
+
+psMetadataItem* psMetadataItemAllocV(const char *name, psMetadataType type, const char *comment,
+                                     va_list argPtr)
+{
+    psVector *vecIn = NULL;
+    psVector *vecOut = NULL;
+    psMetadataItem* metadataItem = NULL;
+
+
+    if (name == NULL) {
+        psError(__func__, "Null value for name not allowed");
+        return NULL;
+    }
+    // Allocate metadata item
+    metadataItem = (psMetadataItem* ) psAlloc(sizeof(psMetadataItem));
+
+    // Set deallocator
+    p_psMemSetDeallocator(metadataItem, (psFreeFcn) metadataItemFree);
+
+    // Allocate and set metadata item comment
+    metadataItem->comment = (char *)psAlloc(sizeof(char) * MAX_STRING_LENGTH);
+    if (comment == NULL) {
+        // Per SDRS, null isn't allowed, must use "" instead
+        strncpy(metadataItem->comment, "", MAX_STRING_LENGTH);
+    } else {
+        strncpy(metadataItem->comment, comment, MAX_STRING_LENGTH);
+    }
+
+    // Set metadata item unique id
+    *(int *)(&metadataItem->id) = ++metadataId;
+
+    // Set metadata item type
+    metadataItem->type = type;
+
+    // Set metadata item value
+    switch (type) {
+    case PS_META_ITEM_SET:
+        metadataItem->data.V = NULL;
+        break;
+    case PS_META_BOOL:
+        metadataItem->data.B = (bool)va_arg(argPtr, int);
+        break;
+    case PS_META_S32:
+        metadataItem->data.S32 = (psS32)va_arg(argPtr, psS32);
+        break;
+    case PS_META_F32:
+        metadataItem->data.F32 = (psF32)va_arg(argPtr, psF64);
+        break;
+    case PS_META_F64:
+        metadataItem->data.F64 = va_arg(argPtr, psF64);
+        break;
+    case PS_META_STR:
+        metadataItem->data.V = psStringNCopy(va_arg(argPtr, char *), MAX_STRING_LENGTH);
+        break;
+    case PS_META_VEC:
+        vecIn = (psVector*)va_arg(argPtr, psVector*);
+        vecOut = psVectorAlloc(vecIn->nalloc, vecIn->type.type);
+        memcpy(vecOut->data.V, vecIn->data.V, vecIn->nalloc*PSELEMTYPE_SIZEOF(vecIn->type.type));
+        metadataItem->data.V = vecOut;
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+    default:
+        psError(__func__, "Invalid psMetadataType: %d", type);
+    }
+
+    // Allocate and set metadata item name
+    metadataItem->name = (char *)psAlloc(sizeof(char) * MAX_STRING_LENGTH);
+    vsprintf(metadataItem->name, name, argPtr);
+
+    // Allocate metadata items with same name.
+    metadataItem->items = psListAlloc(NULL);
+
+    return metadataItem;
+}
+
+psMetadata* psMetadataAlloc(void)
+{
+    psList* list = NULL;
+    psHash* table = NULL;
+    psMetadata* metadata = NULL;
+
+    // Allocate metadata
+    metadata = (psMetadata* ) psAlloc(sizeof(psMetadata));
+    // Set deallocator
+    p_psMemSetDeallocator(metadata, (psFreeFcn) metadataFree);
+
+    // Allocate metadata's internal containers
+    list = (psList* ) psListAlloc(NULL);
+
+    table = (psHash* ) psHashAlloc(10);
+
+    metadata->list = list;
+    metadata->table = table;
+
+    return metadata;
+}
+
+bool psMetadataAddItem( psMetadata *restrict md, psMetadataItem *restrict metadataItem, int location )
+{
+    char * key = NULL;
+    psHash *mdTable = NULL;
+    psList *mdList = NULL;
+    psMetadataItem *existingEntry = NULL;
+    psMetadataItem *newFolderEntry = NULL;
+    psMetadataType newType = PS_META_ITEM_SET;
+
+    if(md == NULL) {
+        psError( __func__, "Null metadata collection not allowed" );
+        return false;
+    }
+
+    if(metadataItem == NULL) {
+        psError( __func__, "Null metadata item not allowed" );
+        return false;
+    }
+
+    newType = metadataItem->type;
+
+    mdTable = md->table;
+    if(mdTable == NULL) {
+        psError( __func__, "Null metadata table not allowed" );
+        return false;
+    }
+
+    mdList = md->list;
+    if(mdList == NULL) {
+        psError( __func__, "Null metadata list not allowed");
+        return false;
+    }
+
+    key = metadataItem->name;
+    if(key == NULL) {
+        psError(__func__, "Null key item not allowed");
+        return false;
+    }
+
+    // See if key is already in table
+    existingEntry = (psMetadataItem*)psHashLookup(mdTable, key);
+    if(existingEntry != NULL) {
+
+        if(existingEntry->type == PS_META_ITEM_SET) {
+
+            // Add leaf node to existing folder node
+            if(!psListAdd(existingEntry->items, PS_LIST_TAIL, metadataItem)) {
+                psError( __func__, "Couldn't add metadata item to items list. Name: %s",
+                         metadataItem->name );
+                return false;
+            }
+        } else if(existingEntry->type != PS_META_ITEM_SET && newType!= PS_META_ITEM_SET) {
+
+            // Leaf node replaces another leaf. Make new folder node and add leaves.
+            newFolderEntry = psMetadataItemAlloc(key, PS_META_ITEM_SET, NULL, NULL);
+
+            if(!psListAdd(newFolderEntry->items, PS_LIST_TAIL, existingEntry)) {
+                psError( __func__, "Couldn't add metadata item to items list. Name: %s", key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psListAdd(newFolderEntry->items, PS_LIST_TAIL, metadataItem)) {
+                psError( __func__, "Couldn't add metadata item to items list. Name: %s", key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psHashRemove(mdTable, key)) {
+                psError( __func__, "Couldn't remove metadata item from metadata table. Name: %s", key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            if(!psHashAdd(mdTable, key, newFolderEntry)) {
+                psError( __func__, "Couldn't add metadata item to metadata table. Name: %s", key);
+                psFree(newFolderEntry);
+                return false;
+            }
+
+            // Remove local reference to new folder node
+            psMemDecrRefCounter(newFolderEntry);
+        } else {
+
+            // Folder node replaces leaf or folder node - Put old node into new folder and remove from table
+            if(!psListAdd(metadataItem->items, PS_LIST_TAIL, existingEntry)) {
+                psError( __func__, "Couldn't add metadata item to items list. Name: %s", key);
+                return false;
+            }
+
+            if(!psHashRemove(mdTable, key)) {
+                psError( __func__, "Couldn't remove metadata item from metadata table. Name: %s", key);
+                return false;
+            }
+
+            if(!psHashAdd(mdTable, key, metadataItem)) {
+                psError( __func__, "Couldn't add metadata item to metadata table. Name: %s", key);
+                return false;
+            }
+        }
+    } else {
+
+        // Node doesn't exist - Add new metadata item to metadata collection's hash
+        if(!psHashAdd(mdTable, key, metadataItem)) {
+            psError( __func__, "Couldn't add metadata item to metadata table. Name: %s", key);
+            return false;
+        }
+    }
+
+    // Add items to metadata collection's list, even if they have the same metadata item names. Folder nodes
+    // (PS_META_ITEM_SET metadata items) are not added, since the metadata list is flat.
+    if(metadataItem->type != PS_META_ITEM_SET) {
+        if(!psListAdd(mdList, location, metadataItem)) {
+            psError( __func__, "Couldn't add metadata item to metadata collection list. Name: %s",
+                     metadataItem->name );
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool psMetadataAdd(psMetadata* restrict md, int where, const char *name, psMetadataType type,
+                   const char *comment, ...)
+{
+    va_list argPtr;
+    psMetadataItem* metadataItem = NULL;
+
+    va_start(argPtr, comment);
+    metadataItem = psMetadataItemAllocV(name, type, comment, argPtr);
+    va_end(argPtr);
+
+    if (!psMetadataAddItem(md, metadataItem, where)) {
+        psError(__func__, "Couldn't add metadata item to metadata collection list. Name: %s",
+                metadataItem->name);
+        psFree(metadataItem);
+        return false;
+    }
+    // Decrement reference count, since the metadata item is now in metadata collection and no longer needed
+    psMemDecrRefCounter(metadataItem);
+
+    return true;
+}
+
+bool psMetadataRemove(psMetadata* restrict md, int where, const char *restrict key)
+{
+    int numChildren = 0;
+    psList* mdList = NULL;
+    psHash* mdTable = NULL;
+    psMetadataItem* entry = NULL;
+    psMetadataItem* entryChild = NULL;
+
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return false;
+    }
+
+    mdList = md->list;
+    if (mdList == NULL) {
+        psError(__func__, "Null metadata list not allowed");
+        return false;
+    }
+
+    mdTable = md->table;
+    if (mdTable == NULL) {
+        psError(__func__, "Null metadata table not allowed");
+        return false;
+    }
+    // Select removal by key or index
+    if (key != NULL) {
+
+        // Remove by key name
+        entry = (psMetadataItem* ) psHashLookup(mdTable, key);
+        if (entry == NULL) {
+            psError(__func__, "Couldn't find metadata item. Name: %s", key);
+            return false;
+        }
+
+        numChildren = entry->items->size;
+        if (entry->type == PS_META_ITEM_SET && numChildren > 0) {
+
+            // Table entry has children. Entry and children must be removed from metadata collection's list
+            psListSetIterator(entry->items, PS_LIST_HEAD);
+            entryChild = psListGetCurrent(entry->items);
+            while (entryChild != NULL) {
+                if (!psListRemove(mdList, PS_LIST_UNKNOWN, entryChild)) {
+                    psError(__func__, "Couldn't remove metadata item from list. Name: %s", key);
+                    return false;
+                }
+                entryChild = psListGetNext(entry->items);
+            }
+        } else {
+
+            // Table entry has no children. Remove entry from metadata collection's list
+            if (!psListRemove(mdList, PS_LIST_UNKNOWN, entry)) {
+                psError(__func__, "Couldn't remove metadata item from list. Name: %s", key);
+                return false;
+            }
+        }
+        // Remove entry from metadata collection's table
+        if (!psHashRemove(mdTable, key)) {
+            psError(__func__, "Couldn't remove metadata item from table. Name: %s", key);
+            return false;
+        }
+    } else {
+
+        // Remove by index
+        entry = psListGet(mdList, where);
+        if (entry == NULL) {
+            psError(__func__, "Couldn't find metadata item in list. Index: %d", where);
+            return false;
+        }
+
+        key = entry->name;
+        if (key == NULL) {
+            psError(__func__, "Null key name not allowed. Index: %d", where);
+            return false;
+        }
+        // Use recursive remove, now that key is known
+        psMetadataRemove(md, PS_LIST_UNKNOWN, key);
+    }
+
+    return true;
+}
+
+psMetadataItem* psMetadataLookup(psMetadata* restrict md, const char *restrict key)
+{
+    psHash* mdTable = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return NULL;
+    }
+
+    mdTable = md->table;
+    if (mdTable == NULL) {
+        psError(__func__, "Null metadata table not allowed");
+        return NULL;
+    }
+
+    if (key == NULL) {
+        psError(__func__, "Null key name not allowed");
+        return NULL;
+    }
+
+    entry = (psMetadataItem* ) psHashLookup(mdTable, key);
+    if (entry == NULL) {
+        return NULL;
+    }
+
+    return entry;
+}
+
+psMetadataItem* psMetadataGet(psMetadata* restrict md, int where)
+{
+    psList* mdList = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return NULL;
+    }
+
+    mdList = md->list;
+    if (mdList == NULL) {
+        psError(__func__, "Null metadata list not allowed");
+        return NULL;
+    }
+
+    entry = (psMetadataItem* ) psListGet(mdList, where);
+    if (entry == NULL) {
+        psError(__func__, "Couldn't find metadata item with given index. Index: %d", where);
+        return NULL;
+    }
+
+    return entry;
+}
+
+bool psMetadataSetIterator(psMetadata* restrict md, int where)
+{
+    psList* mdList = NULL;
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return false;
+    }
+
+    mdList = md->list;
+    if (mdList == NULL) {
+        psError(__func__, "Null metadata list not allowed");
+        return false;
+    }
+
+    psListSetIterator(mdList, where);
+
+    return true;
+}
+
+psMetadataItem* psMetadataGetNext(psMetadata* restrict md, const char *restrict match, int which)
+{
+    psList* mdList = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return NULL;
+    }
+
+    mdList = md->list;
+    if (mdList == NULL) {
+        psError(__func__, "Null metadata list not allowed");
+        return NULL;
+    }
+
+    psListSetIterator(mdList, which);
+    entry = psListGetCurrent(mdList);
+    while (entry != NULL) {
+        if(match != NULL) {
+            if (!strncmp(match, entry->name, strlen(match))) {
+
+                // Match found
+                return entry;
+            }
+            entry = psListGetNext(mdList);
+        } else {
+            entry = psListGetNext(mdList);
+            break;
+        }
+    }
+
+    return entry;
+}
+
+psMetadataItem* psMetadataGetPrevious(psMetadata* restrict md, const char *restrict match, int which)
+{
+    psList* mdList = NULL;
+    psMetadataItem* entry = NULL;
+
+
+    if (md == NULL) {
+        psError(__func__, "Null metadata collection not allowed");
+        return NULL;
+    }
+
+    mdList = md->list;
+    if (mdList == NULL) {
+        psError(__func__, "Null metadata list not allowed");
+        return NULL;
+    }
+
+    psListSetIterator(mdList, which);
+    entry = psListGetCurrent(mdList);
+    while (entry != NULL) {
+        if(match != NULL) {
+            if (!strncmp(match, entry->name, strlen(match))) {
+
+                // Match found
+                return entry;
+            }
+            entry = psListGetPrevious(mdList);
+        } else {
+            entry = psListGetPrevious(mdList);
+            break;
+        }
+    }
+
+    return entry;
+}
Index: /branches/rel3/psLib/src/types/psMetadata.h
===================================================================
--- /branches/rel3/psLib/src/types/psMetadata.h	(revision 2163)
+++ /branches/rel3/psLib/src/types/psMetadata.h	(revision 2163)
@@ -0,0 +1,247 @@
+
+/** @file  psMetadata.h
+*
+*  @brief Contains metadata struuctures, enumerations and functions prototypes
+*
+*  This file defines metadata item, metadata type, metadata flags, metadata containers, and function
+*  prototypes necessary creating psLib metadata APIs
+*
+*  @ingroup Metadata
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.23 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-06 01:06:27 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#ifndef PS_METADATA_H
+#define PS_METADATA_H
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "psHash.h"
+#include "psList.h"
+
+/// @addtogroup Metadata
+/// @{
+
+/** Metadata item type.
+ *
+ * Enumeration for maintaining metadata item types.
+ */
+typedef enum {
+    PS_META_ITEM_SET = 0,              ///< Null. Metadata is in psMetadataItem.items
+    PS_META_BOOL,                      ///< Boolean data.
+    PS_META_S32,                       ///< Signed 32-bit integer data.
+    PS_META_F32,                       ///< Single-precision float data.
+    PS_META_F64,                       ///< Double-precision float data.
+    PS_META_STR,                       ///< String data (Stored in as void *).
+    PS_META_VEC,                       ///< Vector data (Stored in as void *).
+    PS_META_IMG,                       ///< Image data (Stored in as void *).
+    PS_META_JPEG,                      ///< JPEG data (Stored in as void *).
+    PS_META_PNG,                       ///< PNG data (Stored in as void *).
+    PS_META_ASTROM,                    ///< Astrometric coefficients (Stored in as void *).
+    PS_META_UNKNOWN,                   ///< Other data (Stored in as void *).
+    PS_META_NTYPE                      ///< Number of types. Must be last.
+} psMetadataType;
+
+/** Metadata item data structure.
+ *
+ * Struct for maintaining metadata items of varying types. It also contains
+ * information about the item name, flags, comments, and other items with the same name.
+ */
+typedef struct psMetadataItem
+{
+    const int id;                      ///< Unique ID for metadata item.
+    char *restrict name;               ///< Name of metadata item.
+    psMetadataType type;               ///< Type of metadata item.
+    union {
+        bool B;                        ///< boolean data
+        psS32 S32;                     ///< Signed 32-bit integer data.
+        psF32 F32;                     ///< Single-precision float data.
+        psF64 F64;                     ///< Double-precision float data.
+        psPTR V;                       ///< Pointer to other type of data.
+    } data;                            ///< Union for data types.
+    char *comment;                     ///< Optional comment ("", not NULL).
+    psList* restrict items;            ///< List of psMetadataItems with same name.
+}
+psMetadataItem;
+
+/** Metadata data structure.
+ *
+ *  Struct for holding metadata items. Metadata items are held in two
+ *  containers. The first employs a doubly-linked list to preserve the order
+ *  of the metadata. The second container employs a hash table which
+ *  allows fast lookup when given a metadata keyword.
+ */
+typedef struct psMetadata
+{
+    psList* restrict list;             ///< the metadata in linked-list
+    psHash* restrict table;            ///< the metadata in a hash table
+}
+psMetadata;
+
+/** Create a metadata item.
+ *
+ *  Returns a fill psMetadataItem ready for insertion into the psMetadata
+ *  struct. The name argument specifies the name to use for this item, and
+ *  may include sprintf formatting codes. The format entry specifies both
+ *  the metadata type and optional flags and is created by bit-wise or of the
+ *  appropriate type and flag. The comment argument is a fixed string used to
+ *  comment the metadata item. The arguments to the name formatting codes and
+ *  the metadata itself are passed as arguments following the comment string.
+ *  The data must be a pointer for any of the elements stored in data.void.
+ *  The argument list must be interpreted appropriately by the va_list
+ *  operators in the function specified size and type.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataItemAlloc(
+    const char *name,                  ///< Name of metadata item.
+    psMetadataType type,               ///< Type of metadata item.
+    const char *comment,               ///< Comment for metadata item.
+    ...                                ///< Arguments for name formatting and metadata item data.
+);
+
+/** Create a metadata item with va_list.
+ *
+ *  Returns a fill psMetadataItem ready for insertion into the psMetadata
+ *  struct. The name argument specifies the name to use for this item, and
+ *  may include sprintf formatting codes. The format entry specifies both
+ *  the metadata type and optional flags and is created by bit-wise or of the
+ *  appropriate type and flag. The comment argument is a fixed string used to
+ *  comment the metadata item. The arguments to the name formatting codes and
+ *  the metadata itself are passed as arguments following the comment string.
+ *  The data must be a pointer for any of the elements stored in data.void.
+ *  The argument list must be interpreted appropriately by the va_list
+ *  operators in the function specified size and type.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataItemAllocV(
+    const char *name,                  ///< Name of metadata item.
+    psMetadataType type,               ///< Type of metadata item.
+    const char *comment,               ///< Comment for metadata item.
+    va_list list                       ///< Arguments for name formatting and metadata item data.
+);
+
+/** Create a metadata collection.
+ *
+ *  Returns an empty metadata container with fully allocated internal metadata
+ *  containers.
+ *
+ *  @return psMetadata* : Pointer metadata.
+ */
+psMetadata* psMetadataAlloc(void);
+
+/** Add existing metadata item to metadata collection.
+ *
+ *  Add a metadata item that has already been created to the metadata
+ *  collection.
+ *
+ *  @return bool: True for success, false for failure.
+ */
+bool psMetadataAddItem(
+    psMetadata* restrict md,           ///< Metadata collection to insert metadat item.
+    psMetadataItem* restrict item,     ///< Metadata item to be added.
+    int location                       ///< Location to be added.
+);
+
+/** Create and add a metadata item to metadata collection.
+ *
+ * Creates a new metadata item add to the metadata collection.
+ *
+ * @return bool: True for success, false for failure.
+ */
+bool psMetadataAdd(
+    psMetadata* restrict md,           ///< Metadata collection to insert metadat item.
+    int where,                         ///< Location to be added.
+    const char *name,                  ///< Name of metadata item.
+    psMetadataType type,               ///< Type of metadata item.
+    const char *comment,               ///< Comment for metadata item.
+    ...                                ///< Arguments for name formatting and metadata item data.
+);
+
+/** Remove an item from metadata collection.
+ *
+ *  Items may be removed from metadata by specifing a key or location. If the
+ *  name is null, the where argument is used instead. If name is not null,
+ *  where is set to PS_LIST_UNKNOWN. If the item is found, it is removed from
+ *  the metadata and true is returned.  If the key is not unique, then all
+ *  items corresponding to it are removed.
+ *
+ * @return bool: True for success, false for failure.
+ */
+bool psMetadataRemove(
+    psMetadata* restrict md,           ///< Metadata collection to insert metadat item.
+    int where,                         ///< Location to be removed.
+    const char *restrict key           ///< Name of metadata key.
+);
+
+/** Find an item in the metadata collection based on key name.
+ *
+ *  Items may be found in the metadata by providing a key. If the key is
+ *  non-unique, the first item is returned. If the item is not found, null is
+ *  returned.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataLookup(
+    psMetadata* restrict md,           ///< Metadata collection to insert metadata item.
+    const char *restrict key           ///< Name of metadata key.
+);
+
+/** Find an item in the metadata collection based on list index.
+ *
+ *  Items may be found in the metadata by their entry position in the list
+ *  container.
+ *
+ *  @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataGet(
+    psMetadata* restrict md,           ///< Metadata collection to insert metadat item.
+    int where                          ///< Location to be retrieved.
+);
+
+/** Set or reset metadata iterator.
+ *
+ *  Metadata may be iterated by setting or resetting an iterator to a location
+ *  in the metadata list.
+ *
+ * @return void: void.
+ */
+bool psMetadataSetIterator(
+    psMetadata* restrict md,           ///< Metadata collection to iterate.
+    int where                          ///< Location of iterator.
+);
+
+/** Get next metadata item.
+ *
+ * Get next metadata item in iterator list.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataGetNext(
+    psMetadata* restrict md,           ///< Metadata collection to iterate.
+    const char *restrict match,        ///< Beginning of key name.
+    int which                          ///< Iterator to be used.
+);
+
+/** Get previous metadata item.
+ *
+ * Get previous metadata item in iterator list.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+psMetadataItem* psMetadataGetPrevious(
+    psMetadata* restrict md,           ///< Metadata collection to iterate.
+    const char *restrict match,        ///< Beginning of key name.
+    int which                          ///< Iterator to be used.
+);
+
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/types/psMetadataConfig.c
===================================================================
--- /branches/rel3/psLib/src/types/psMetadataConfig.c	(revision 2163)
+++ /branches/rel3/psLib/src/types/psMetadataConfig.c	(revision 2163)
@@ -0,0 +1,662 @@
+/** @file  psMetadataIO.c
+*
+*  @brief Contains metadata input/output functions.
+*
+*  This file defines functions to read and write metadata to/from an external file.
+*
+*  @ingroup Metadata
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-08 00:43:12 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include <fitsio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "psAbort.h"
+#include "psType.h"
+#include "psMemory.h"
+#include "psError.h"
+#include "psString.h"
+#include "psList.h"
+#include "psHash.h"
+#include "psVector.h"
+#include "psMetadata.h"
+#include "psMetadataIO.h"
+
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Check for FITS errors */
+#define FITS_ERROR(STRING,PS_ERROR) \
+fits_get_errstatus(status, fitsErr); \
+psError(__func__, STRING, PS_ERROR, fitsErr); \
+status = 0; \
+fits_close_file(fd, &status); \
+if(status){ \
+    fits_get_errstatus(status, fitsErr); \
+    psError(__func__, "Couldn't close FITS file. FITS error: %s", fitsErr); \
+} \
+status = 0; \
+psFree(output); \
+return NULL;
+
+/** Free and null temporary variables used by config file parser */
+#define CLEAR_TEMPS()                                                                                        \
+if(strName) {                                                                                            \
+    psFree(strName);                                                                                     \
+    strName = NULL;                                                                                      \
+}                                                                                                        \
+if(strType) {                                                                                            \
+    psFree(strType);                                                                                     \
+    strType = NULL;                                                                                      \
+}                                                                                                        \
+if(strValue) {                                                                                           \
+    psFree(strValue);                                                                                    \
+    strValue = NULL;                                                                                     \
+}                                                                                                        \
+if(strComment) {                                                                                         \
+    psFree(strComment);                                                                                  \
+    strComment = NULL;                                                                                   \
+}                                                                                                        \
+if(tempVec) {                                                                                            \
+    psFree(tempVec);                                                                                     \
+    tempVec = NULL;                                                                                      \
+}
+
+/** Maximum size of a FITS line */
+#define FITS_LINE_SIZE 80
+
+/** Maximum size of a string */
+#define MAX_STRING_LENGTH 256
+
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+
+/** Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string
+ *  must be null terminated. */
+bool ignoreLine(char *inString)
+{
+    while(*inString!='\0' && *inString!='#') {
+        if(!isspace(*inString)) {
+            return false;
+        }
+        inString++;
+    }
+
+    return true;
+}
+
+
+/** Removes leading and trailing whitespace and # characters from a string. The cleaned string is a new null
+ *  terminated copy of the original input string. */
+char *cleanString(char *inString, int sLen)
+{
+    char *ptrB = NULL;
+    char *ptrE = NULL;
+    char *cleaned = NULL;
+
+
+    ptrB = inString;
+
+    /* Skip over leading # or whitespace */
+    while (isspace(*ptrB) || *ptrB=='#') {
+        ptrB++;
+    }
+
+    /* Skip over trailing whitespace, null terminators, and # characters */
+    ptrE = inString + sLen;
+    while(isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') {
+        ptrE--;
+    }
+
+    // Length, sLen, does not include '\0'
+    sLen = ptrE - ptrB + 1;
+
+    // Adds '\0' to end of string and +1 to sLen
+    cleaned = psStringNCopy(ptrB, sLen);
+
+    return cleaned;
+}
+
+/** Count repeat occurances of a single character within a line. The input string must be null terminated. */
+int repeatedChars(char *inString, char ch)
+{
+    int count = 0;
+
+
+    while(*inString!='\0') {
+        if(*inString == ch) {
+            count++;
+        }
+        inString++;
+    }
+
+    return count;
+}
+
+/** Returns cleaned token based on delimiter, but not including delimiter. Also changes the pointer location
+ * the beginning of the string. Tokens are newly allocated null terminated strings. */
+char* getToken(char **inString, char *delimiter, int *status)
+{
+    char *cleanToken = NULL;
+    int sLen = 0;
+
+
+    // Skip over leading whitespace
+    while(isspace(**inString)) {
+        (*inString)++;
+    }
+
+    // Length of token, not including delimiter
+    sLen = strcspn(*inString, delimiter);
+    if(sLen) {
+
+        // Create new, cleaned, and null terminated token
+        cleanToken = cleanString(*inString, sLen);
+
+        // Move to end of token
+        (*inString) += sLen;
+    } else if(**inString!='\0' && sLen==0) {
+        *status = 1;
+    }
+
+    return cleanToken;
+}
+
+/** Returns single parsed value as a double precision number. The input string must be cleaned and null
+ * terminated. */
+double parseValue(char *inString, int *status)
+{
+    char *end = NULL;
+    double value = 0.0;
+
+
+    value = strtod(inString, &end);
+    if(*end != '\0') {
+        *status = 1;
+    } else if(inString==end) {
+        *status = 1;
+    }
+
+    return value;
+}
+
+/** Returns true or false. 'T', 't', '1', 'F', 'f', and '0' are acceptable, parsable variations. */
+bool parseBool(char *inString, int *status)
+{
+    bool value = false;
+
+
+    if(*inString=='T' || *inString=='t' || *inString=='1') {
+        value = true;
+    } else if(*inString=='F' || *inString=='f' || *inString=='0') {
+        value = false;
+    } else {
+        *status = 1;
+    }
+
+    return value;
+}
+
+/** Returns parsed vector filled with with data. The input string must be null terminated. */
+psVector* parseVector(char *inString, psElemType elemType, int *status)
+{
+    char *end = NULL;
+    char *saveValue = NULL;
+    int i = 0;
+    int numValues = 0;
+    double value = 0.0;
+    psVector *vec = NULL;
+
+
+    // Cycle through string and count entries
+    saveValue = inString;
+    while(*inString!='\0') {
+        strtod(inString, &end);
+        if(inString==end) {
+            *status = 1;
+            return NULL;
+        }
+        while(*end==' ' || *end==',') { // Commas or spaces may be used as delimiters for vector values
+            end++;
+        }
+        inString=end;
+        numValues++;
+    }
+
+    // Cycle through string and convert string values to values
+    if(numValues) {
+        inString = saveValue;
+        end = NULL;
+        vec = psVectorAlloc(numValues, elemType);
+
+        while(*inString!='\0') {
+            value = strtod(inString, &end);
+            if(inString==end) {
+                *status = 1;
+                return vec;
+            }
+            switch(elemType) {
+            case PS_TYPE_U8:
+                vec->data.U8[i++] = (psU8)value;
+                break;
+            case PS_TYPE_S32:
+                vec->data.S32[i++] = (psS32)value;
+                break;
+            case PS_TYPE_F32:
+                vec->data.F32[i++] = (psF32)value;
+                break;
+            case PS_TYPE_F64:
+                vec->data.F64[i++] = (psF64)value;
+                break;
+            default:
+                *status = 1;
+                psError(__func__, "Invalid type: %d", elemType);
+            }
+
+            while(*end==' ' || *end==',') {
+                end++;
+            }
+            inString=end;
+        }
+    }
+
+    return vec;
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+void psMetadataItemPrint(FILE * fd, const char *format, const psMetadataItem* restrict metadataItem)
+{
+    psMetadataType type;
+
+    if (fd == NULL) {
+        psError(__func__, "Null file descriptor not allowed");
+        return;
+    }
+
+    if (format == NULL) {
+        psError(__func__, "Null format not allowed");
+        return;
+    }
+
+    if (metadataItem == NULL) {
+        psError(__func__, "Null metadata not allowed");
+        return;
+    }
+
+    type = metadataItem->type;
+
+    switch(type) {
+    case PS_META_BOOL:
+        fprintf(fd, format, metadataItem->data.B);
+        break;
+    case PS_META_S32:
+        fprintf(fd,format, metadataItem->data.S32);
+        break;
+    case PS_META_F32:
+        fprintf(fd, format, metadataItem->data.F32);
+        break;
+    case PS_META_F64:
+        fprintf(fd, format, metadataItem->data.F64);
+        break;
+    case PS_META_STR:
+        fprintf(fd, format, metadataItem->data.V);
+        break;
+    default:
+        psError(__func__, " Invalid psMetadataType to print: %d", type);
+    }
+}
+
+
+psMetadata* psMetadataReadHeader(psMetadata* output, char *extName, int extNum, char *fileName)
+{
+    bool tempBool;
+    bool success;
+    char keyType;
+    char keyName[FITS_LINE_SIZE];
+    char keyValue[FITS_LINE_SIZE];
+    char keyComment[FITS_LINE_SIZE];
+    char fitsErr[MAX_STRING_LENGTH];
+    int i;
+    int hduType = 0;
+    int status = 0;
+    int numKeys = 0;
+    int keyNum = 0;
+    psMetadataType metadataItemType;
+    fitsfile *fd = NULL;
+
+    if(fileName == NULL) {
+        psError(__func__, "Null fileName not allowed");
+        return NULL;
+    }
+
+    fits_open_file(&fd, fileName, READONLY, &status);
+    if(fd == NULL || status != 0) {
+        FITS_ERROR("FITS error while opening file: %s %s", fileName);
+        return NULL;
+    }
+
+    if (extName == NULL && extNum == 0) {
+        psError(__func__, "Null extName and extNum = 0 not allowed");
+        return NULL;
+    } else if (extName && (extNum != -1) ) {
+        psError(__func__, "If extName specified, extNum arguments should be -1.");
+        return NULL;
+    }
+
+    // Allocate metadata if user didn't
+    if (output == NULL) {
+        output = psMetadataAlloc();
+    }
+
+    // Move to user designated HDU number or HDU name in FITS file. HDU numbers starts at one.
+    if (extName != NULL) {
+        if (fits_movnam_hdu(fd, ANY_HDU, extName, 0, &status) != 0) {
+            FITS_ERROR("FITS error while locating header %s: %s", extName);
+        }
+    } else {
+        if (fits_movabs_hdu(fd, extNum, &hduType, &status) != 0) {
+            FITS_ERROR("FITS error while locating header %d: %s", extNum);
+        }
+    }
+
+    // Get number of key names
+    if (fits_get_hdrpos(fd, &numKeys, &keyNum, &status) != 0) {
+        FITS_ERROR("FITS error while reading key %d: %s", keyNum);
+    }
+
+    // Get each key name. Keywords start at one.
+    for (i = 1; i <= numKeys; i++) {
+        if (fits_read_keyn(fd, i, keyName, keyValue, keyComment, &status) != 0) {
+            FITS_ERROR("FITS error while reading key %d: %s", keyNum);
+        }
+        if (fits_get_keytype(keyValue, &keyType, &status) != 0) {
+            fits_get_errstatus(status, fitsErr);
+            if (status != VALUE_UNDEFINED) {
+                FITS_ERROR("FITS error while determining key %d type: %s", keyNum);
+            } else {
+                // Some keywords are still valid if they don't have a type (like COMMENTS and HISTORY)
+                keyType = 'C';
+                status = 0;
+            }
+        }
+
+        switch (keyType) {
+        case 'I':
+            metadataItemType = PS_META_S32;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, metadataItemType, keyComment, atoi(keyValue));
+            break;
+        case 'F':
+            metadataItemType = PS_META_F64;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, metadataItemType, keyComment, atof(keyValue));
+            break;
+        case 'C':
+            metadataItemType = PS_META_STR;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, metadataItemType, keyComment, keyValue);
+            break;
+        case 'L':
+            metadataItemType = PS_META_BOOL;
+            tempBool = (keyValue[0] == 'T') ? 1 : 0;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, metadataItemType, keyComment, tempBool);
+            break;
+        case 'U':
+        case 'X':
+        default:
+            psError(__func__, "Invalid psMetadataType: %c", keyType);
+            return output;
+        }
+
+        if (!success) {
+            psError(__func__, "Failed to add metadata item. Name: %s", keyName);
+            return output;
+        }
+    }
+
+    return output;
+}
+
+
+int psMetadataParseConfig(psMetadata** md, char *fileName, bool overwrite)
+{
+    bool tempBool;
+    char *line = NULL;
+    char *strName = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    char *strComment = NULL;
+    char *linePtr = NULL;
+    int status = 0;
+    int lineCount = 0;
+    int failedLines = 0;
+    psF64 tempDbl = 0.0;
+    psS32 tempInt = 0.0;
+    psMetadataItem *metadataItem = NULL;
+    psVector *tempVec = NULL;
+    FILE *fp = NULL;
+    psElemType elemType;
+    psMetadataType mdType;
+
+
+    // Check for nulls
+    if(fileName == NULL) {
+        psError(__func__, "Null fileName not allowed");
+        return -1;
+    } else if((fp=fopen(fileName, "r")) == NULL) {
+        psError(__func__, "Couldn't open file. Name: %s", fileName);
+        return -1;
+    }
+
+    // Allocate metadata if necessary
+    if (*md == NULL) {
+        *md = psMetadataAlloc();
+    }
+
+    // Create reusable line for continuous read
+    line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char));
+    if (line == NULL) {
+        psAbort(__func__, "Failed to allocate reusable line");
+    }
+
+    // While loop to parse the file
+    while(fgets(line, MAX_STRING_LENGTH, fp) != NULL) {
+
+        // Initialize variables for new line
+        linePtr = line;
+        lineCount++;
+        CLEAR_TEMPS();
+
+        // If line is not a comment or blank, then extract data
+        if(!ignoreLine(linePtr)) {
+
+            // Check for more than one '*' or '@' in a line
+            if(repeatedChars(linePtr, '@') > 1) {
+                failedLines++;
+                psError(__func__, "More than one @ charecter not allowed. Line %d: %s", lineCount, line);
+                continue;
+            } else if(repeatedChars(linePtr, '*') > 1) {
+                failedLines++;
+                psError(__func__, "More than one * charecter not allowed. Line %d: %s", lineCount, line);
+                continue;
+            } else if(repeatedChars(linePtr, '~') > 0) {
+                failedLines++;
+                psError(__func__, "Illegal character. Character:~ Line %d: %s", lineCount, line);
+                continue;
+            }
+
+            // Get metadata item name
+            strName = getToken(&linePtr, " ", &status);
+            if(strName==NULL || status) {
+                failedLines++;
+                status = 0;
+                psError(__func__, "Null name not allowed. Line %d: %s", lineCount, line);
+                continue;
+            }
+
+            // Get the metadata item type
+            strType = getToken(&linePtr, " ", &status);
+            if(strType==NULL) {
+                failedLines++;
+                status = 0;
+                psError(__func__, "Null type not allowed. Line %d: %s", lineCount, line);
+                continue;
+            } else if(!strncmp(strType, "*", 1)) {
+                mdType = PS_META_ITEM_SET;
+            } else if(!strncmp(strType, "STR", 3)) {
+                mdType = PS_META_STR;
+                elemType = PS_TYPE_PTR;
+            } else if(!strncmp(strType, "BOOL", 3)) {
+                mdType = PS_META_BOOL;
+                elemType = PS_TYPE_U8;
+            } else if(!strncmp(strType, "S32", 3)) {
+                mdType = PS_META_S32;
+                elemType = PS_TYPE_S32;
+            } else if(!strncmp(strType, "F32", 3)) {
+                mdType = PS_META_F32;
+                elemType = PS_TYPE_F32;
+            } else if(!strncmp(strType, "F64", 3)) {
+                mdType = PS_META_F64;
+                elemType = PS_TYPE_F64;
+            } else {
+                failedLines++;
+                psError(__func__, "Invalid psMetadataType. Type: %s Line %d: %s", strType, lineCount, line);
+                continue;
+            }
+
+            if(*strName == '@') {
+                mdType = PS_META_VEC;
+            }
+
+            // Get the metadata item value if there is one. Lines with * don't have values.
+            if(mdType != PS_META_ITEM_SET) {
+                strValue = getToken(&linePtr, "#", &status);
+                if(strValue==NULL) {
+                    failedLines++;
+                    status = 0;
+                    psError(__func__, "Null value not allowed. Line %d: %s", lineCount, line);
+                    continue;
+                }
+            }
+
+            // Get the metadata item value if there is one. Not all lines will have comments, so NULL is ok.
+            strComment = getToken(&linePtr,"~", &status);
+            if(status) {
+                failedLines++;
+                status = 0;
+                psError(__func__, "Failed to parse comment. Line %d: %s", lineCount, line);
+                continue;
+            }
+
+            /* If metadata item is found, is not a folder node, and overwrite is allowed, then remove existing
+            and allow switch/case below to add new item. If overwrite is false, then report error. If found
+            item is folder node, then psMetadataAdd will automatically add a new child. */
+            metadataItem = psMetadataLookup(*md, strName);
+            if(metadataItem != NULL) {
+                if(metadataItem->type!=PS_META_ITEM_SET) {
+                    if(overwrite) {
+                        psMetadataRemove(*md, PS_LIST_UNKNOWN, strName);
+                    } else {
+                        failedLines++;
+                        psError(__func__, "Overwrite for name not allowed. Name: %s. Line %d: %s", strName,
+                                lineCount, line);
+                        continue;
+                    }
+                }
+            }
+
+            // Create and add metadata item to metadata and parse values
+            switch (mdType) {
+            case PS_META_ITEM_SET:
+                psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, NULL, NULL);
+                break;
+            case PS_META_BOOL:
+                tempBool = parseBool(strValue, &status);
+                if(!status) {
+                    psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, strComment, tempBool);
+                } else {
+                    status = 0;
+                    failedLines++;
+                    psError(__func__, "Failed to parse value. Value: %s Line %d: %s", strValue, lineCount, line);
+                    continue;
+                }
+                break;
+            case PS_META_S32:
+                tempInt = (psS32)parseValue(strValue, &status);
+                if(!status) {
+                    psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, strComment, tempInt);
+                } else {
+                    status = 0;
+                    failedLines++;
+                    psError(__func__, "Failed to parse value. Value: %s Line %d: %s", strValue, lineCount, line);
+                    continue;
+                }
+                break;
+            case PS_META_F32:
+            case PS_META_F64:
+                tempDbl = parseValue(strValue, &status);
+                if(!status) {
+                    psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, strComment, tempDbl);
+                } else {
+                    status = 0;
+                    failedLines++;
+                    psError(__func__, "Failed to parse value. Value: %s Line %d: %s", strValue, lineCount, line);
+                    continue;
+                }
+                break;
+            case PS_META_STR:
+                psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, strComment, strValue);
+                break;
+            case PS_META_VEC:
+                tempVec = parseVector(strValue, elemType, &status);
+                if(!status) {
+                    psMetadataAdd(*md, PS_LIST_TAIL, strName+1, mdType, strComment, tempVec);
+                } else {
+                    status = 0;
+                    failedLines++;
+                    psError(__func__, "Failed to parse value. Value: %s Line %d: %s", strValue, lineCount, line);
+                    continue;
+                }
+                break;
+            default:
+                failedLines++;
+                psError(__func__, "Invalid psMetadataType. Type: %d Line %d: %s", mdType, lineCount, line);
+                continue;
+            } // switch
+        } // if ignoreLine
+    } // while loop
+
+    psFree(line);
+
+    return failedLines;
+}
Index: /branches/rel3/psLib/src/types/psMetadataConfig.h
===================================================================
--- /branches/rel3/psLib/src/types/psMetadataConfig.h	(revision 2163)
+++ /branches/rel3/psLib/src/types/psMetadataConfig.h	(revision 2163)
@@ -0,0 +1,70 @@
+/** @file  psMetadataIO.h
+*
+*  @brief Contains metadata input/output functions.
+*
+*  This file defines functions to read and write metadata to/from an external file.
+*
+*  @ingroup Metadata
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-06 01:17:39 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#ifndef PS_METADATAIO_H
+#define PS_METADATAIO_H
+
+
+/// @addtogroup Metadata
+/// @{
+
+
+/** Print metadata item to file.
+ *
+ *  Metadata items may be printed to an open file descriptor based on a
+ *  provided format. The format is a sprintf format statement with exactly
+ *  one % formatting command. If the metadata item type is a numeric type,
+ *  this formatting command must also be numeric, and the type conversion
+ *  performed to the value to match the format type. If the metadata type is
+ *  a string, the fromatting command must also be for a string. If the
+ *  metadata type is any other data type, printing is not allowed.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+void psMetadataItemPrint(
+    FILE * fd,                         ///< Pointer to file to write metadata item.
+    const char *format,                ///< Format to print metadata item.
+    const psMetadataItem* restrict metadataItem ///< Metadata item to print.
+);
+
+/** Read metadata header.
+ *
+ *  Read a metadata header from file. If the file is not found, an error is
+ *  reported.
+ *
+ *  @return psMetadata* : Pointer to resulting metadata.
+ */
+psMetadata* psMetadataReadHeader(
+    psMetadata* output,                ///< Resulting metadata from read.
+    char *extName,                     ///< File name extension string.
+    int extNum,                        ///< File name extension number. Starts at 1.
+    char *fileName                     ///< Name of file to read.
+);
+
+/** Read metadata configuration file.
+ *
+ *  Loads pre-defined settings by parsing a configuration file into a psMetadata structure.
+ *
+ *  @return int : Number of lines that failed to be read.
+ */
+int psMetadataParseConfig(
+    psMetadata** md,                   ///< Resulting metadata from read.
+    char *fileName,                    ///< Name of file to read.
+    bool overwrite                     ///< Allow overwrite of duplicate specifications.
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/src/xml/psXML.c
===================================================================
--- /branches/rel3/psLib/src/xml/psXML.c	(revision 2163)
+++ /branches/rel3/psLib/src/xml/psXML.c	(revision 2163)
@@ -0,0 +1,662 @@
+/** @file  psMetadataIO.c
+*
+*  @brief Contains metadata input/output functions.
+*
+*  This file defines functions to read and write metadata to/from an external file.
+*
+*  @ingroup Metadata
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-08 00:43:12 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include <fitsio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "psAbort.h"
+#include "psType.h"
+#include "psMemory.h"
+#include "psError.h"
+#include "psString.h"
+#include "psList.h"
+#include "psHash.h"
+#include "psVector.h"
+#include "psMetadata.h"
+#include "psMetadataIO.h"
+
+
+/******************************************************************************/
+/*  DEFINE STATEMENTS                                                         */
+/******************************************************************************/
+
+/** Check for FITS errors */
+#define FITS_ERROR(STRING,PS_ERROR) \
+fits_get_errstatus(status, fitsErr); \
+psError(__func__, STRING, PS_ERROR, fitsErr); \
+status = 0; \
+fits_close_file(fd, &status); \
+if(status){ \
+    fits_get_errstatus(status, fitsErr); \
+    psError(__func__, "Couldn't close FITS file. FITS error: %s", fitsErr); \
+} \
+status = 0; \
+psFree(output); \
+return NULL;
+
+/** Free and null temporary variables used by config file parser */
+#define CLEAR_TEMPS()                                                                                        \
+if(strName) {                                                                                            \
+    psFree(strName);                                                                                     \
+    strName = NULL;                                                                                      \
+}                                                                                                        \
+if(strType) {                                                                                            \
+    psFree(strType);                                                                                     \
+    strType = NULL;                                                                                      \
+}                                                                                                        \
+if(strValue) {                                                                                           \
+    psFree(strValue);                                                                                    \
+    strValue = NULL;                                                                                     \
+}                                                                                                        \
+if(strComment) {                                                                                         \
+    psFree(strComment);                                                                                  \
+    strComment = NULL;                                                                                   \
+}                                                                                                        \
+if(tempVec) {                                                                                            \
+    psFree(tempVec);                                                                                     \
+    tempVec = NULL;                                                                                      \
+}
+
+/** Maximum size of a FITS line */
+#define FITS_LINE_SIZE 80
+
+/** Maximum size of a string */
+#define MAX_STRING_LENGTH 256
+
+
+/******************************************************************************/
+/*  TYPE DEFINITIONS                                                          */
+/******************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  GLOBAL VARIABLES                                                         */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FILE STATIC VARIABLES                                                    */
+/*****************************************************************************/
+
+// None
+
+/*****************************************************************************/
+/*  FUNCTION IMPLEMENTATION - LOCAL                                          */
+/*****************************************************************************/
+
+
+/** Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string
+ *  must be null terminated. */
+bool ignoreLine(char *inString)
+{
+    while(*inString!='\0' && *inString!='#') {
+        if(!isspace(*inString)) {
+            return false;
+        }
+        inString++;
+    }
+
+    return true;
+}
+
+
+/** Removes leading and trailing whitespace and # characters from a string. The cleaned string is a new null
+ *  terminated copy of the original input string. */
+char *cleanString(char *inString, int sLen)
+{
+    char *ptrB = NULL;
+    char *ptrE = NULL;
+    char *cleaned = NULL;
+
+
+    ptrB = inString;
+
+    /* Skip over leading # or whitespace */
+    while (isspace(*ptrB) || *ptrB=='#') {
+        ptrB++;
+    }
+
+    /* Skip over trailing whitespace, null terminators, and # characters */
+    ptrE = inString + sLen;
+    while(isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') {
+        ptrE--;
+    }
+
+    // Length, sLen, does not include '\0'
+    sLen = ptrE - ptrB + 1;
+
+    // Adds '\0' to end of string and +1 to sLen
+    cleaned = psStringNCopy(ptrB, sLen);
+
+    return cleaned;
+}
+
+/** Count repeat occurances of a single character within a line. The input string must be null terminated. */
+int repeatedChars(char *inString, char ch)
+{
+    int count = 0;
+
+
+    while(*inString!='\0') {
+        if(*inString == ch) {
+            count++;
+        }
+        inString++;
+    }
+
+    return count;
+}
+
+/** Returns cleaned token based on delimiter, but not including delimiter. Also changes the pointer location
+ * the beginning of the string. Tokens are newly allocated null terminated strings. */
+char* getToken(char **inString, char *delimiter, int *status)
+{
+    char *cleanToken = NULL;
+    int sLen = 0;
+
+
+    // Skip over leading whitespace
+    while(isspace(**inString)) {
+        (*inString)++;
+    }
+
+    // Length of token, not including delimiter
+    sLen = strcspn(*inString, delimiter);
+    if(sLen) {
+
+        // Create new, cleaned, and null terminated token
+        cleanToken = cleanString(*inString, sLen);
+
+        // Move to end of token
+        (*inString) += sLen;
+    } else if(**inString!='\0' && sLen==0) {
+        *status = 1;
+    }
+
+    return cleanToken;
+}
+
+/** Returns single parsed value as a double precision number. The input string must be cleaned and null
+ * terminated. */
+double parseValue(char *inString, int *status)
+{
+    char *end = NULL;
+    double value = 0.0;
+
+
+    value = strtod(inString, &end);
+    if(*end != '\0') {
+        *status = 1;
+    } else if(inString==end) {
+        *status = 1;
+    }
+
+    return value;
+}
+
+/** Returns true or false. 'T', 't', '1', 'F', 'f', and '0' are acceptable, parsable variations. */
+bool parseBool(char *inString, int *status)
+{
+    bool value = false;
+
+
+    if(*inString=='T' || *inString=='t' || *inString=='1') {
+        value = true;
+    } else if(*inString=='F' || *inString=='f' || *inString=='0') {
+        value = false;
+    } else {
+        *status = 1;
+    }
+
+    return value;
+}
+
+/** Returns parsed vector filled with with data. The input string must be null terminated. */
+psVector* parseVector(char *inString, psElemType elemType, int *status)
+{
+    char *end = NULL;
+    char *saveValue = NULL;
+    int i = 0;
+    int numValues = 0;
+    double value = 0.0;
+    psVector *vec = NULL;
+
+
+    // Cycle through string and count entries
+    saveValue = inString;
+    while(*inString!='\0') {
+        strtod(inString, &end);
+        if(inString==end) {
+            *status = 1;
+            return NULL;
+        }
+        while(*end==' ' || *end==',') { // Commas or spaces may be used as delimiters for vector values
+            end++;
+        }
+        inString=end;
+        numValues++;
+    }
+
+    // Cycle through string and convert string values to values
+    if(numValues) {
+        inString = saveValue;
+        end = NULL;
+        vec = psVectorAlloc(numValues, elemType);
+
+        while(*inString!='\0') {
+            value = strtod(inString, &end);
+            if(inString==end) {
+                *status = 1;
+                return vec;
+            }
+            switch(elemType) {
+            case PS_TYPE_U8:
+                vec->data.U8[i++] = (psU8)value;
+                break;
+            case PS_TYPE_S32:
+                vec->data.S32[i++] = (psS32)value;
+                break;
+            case PS_TYPE_F32:
+                vec->data.F32[i++] = (psF32)value;
+                break;
+            case PS_TYPE_F64:
+                vec->data.F64[i++] = (psF64)value;
+                break;
+            default:
+                *status = 1;
+                psError(__func__, "Invalid type: %d", elemType);
+            }
+
+            while(*end==' ' || *end==',') {
+                end++;
+            }
+            inString=end;
+        }
+    }
+
+    return vec;
+}
+
+/*****************************************************************************/
+/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
+/*****************************************************************************/
+
+void psMetadataItemPrint(FILE * fd, const char *format, const psMetadataItem* restrict metadataItem)
+{
+    psMetadataType type;
+
+    if (fd == NULL) {
+        psError(__func__, "Null file descriptor not allowed");
+        return;
+    }
+
+    if (format == NULL) {
+        psError(__func__, "Null format not allowed");
+        return;
+    }
+
+    if (metadataItem == NULL) {
+        psError(__func__, "Null metadata not allowed");
+        return;
+    }
+
+    type = metadataItem->type;
+
+    switch(type) {
+    case PS_META_BOOL:
+        fprintf(fd, format, metadataItem->data.B);
+        break;
+    case PS_META_S32:
+        fprintf(fd,format, metadataItem->data.S32);
+        break;
+    case PS_META_F32:
+        fprintf(fd, format, metadataItem->data.F32);
+        break;
+    case PS_META_F64:
+        fprintf(fd, format, metadataItem->data.F64);
+        break;
+    case PS_META_STR:
+        fprintf(fd, format, metadataItem->data.V);
+        break;
+    default:
+        psError(__func__, " Invalid psMetadataType to print: %d", type);
+    }
+}
+
+
+psMetadata* psMetadataReadHeader(psMetadata* output, char *extName, int extNum, char *fileName)
+{
+    bool tempBool;
+    bool success;
+    char keyType;
+    char keyName[FITS_LINE_SIZE];
+    char keyValue[FITS_LINE_SIZE];
+    char keyComment[FITS_LINE_SIZE];
+    char fitsErr[MAX_STRING_LENGTH];
+    int i;
+    int hduType = 0;
+    int status = 0;
+    int numKeys = 0;
+    int keyNum = 0;
+    psMetadataType metadataItemType;
+    fitsfile *fd = NULL;
+
+    if(fileName == NULL) {
+        psError(__func__, "Null fileName not allowed");
+        return NULL;
+    }
+
+    fits_open_file(&fd, fileName, READONLY, &status);
+    if(fd == NULL || status != 0) {
+        FITS_ERROR("FITS error while opening file: %s %s", fileName);
+        return NULL;
+    }
+
+    if (extName == NULL && extNum == 0) {
+        psError(__func__, "Null extName and extNum = 0 not allowed");
+        return NULL;
+    } else if (extName && (extNum != -1) ) {
+        psError(__func__, "If extName specified, extNum arguments should be -1.");
+        return NULL;
+    }
+
+    // Allocate metadata if user didn't
+    if (output == NULL) {
+        output = psMetadataAlloc();
+    }
+
+    // Move to user designated HDU number or HDU name in FITS file. HDU numbers starts at one.
+    if (extName != NULL) {
+        if (fits_movnam_hdu(fd, ANY_HDU, extName, 0, &status) != 0) {
+            FITS_ERROR("FITS error while locating header %s: %s", extName);
+        }
+    } else {
+        if (fits_movabs_hdu(fd, extNum, &hduType, &status) != 0) {
+            FITS_ERROR("FITS error while locating header %d: %s", extNum);
+        }
+    }
+
+    // Get number of key names
+    if (fits_get_hdrpos(fd, &numKeys, &keyNum, &status) != 0) {
+        FITS_ERROR("FITS error while reading key %d: %s", keyNum);
+    }
+
+    // Get each key name. Keywords start at one.
+    for (i = 1; i <= numKeys; i++) {
+        if (fits_read_keyn(fd, i, keyName, keyValue, keyComment, &status) != 0) {
+            FITS_ERROR("FITS error while reading key %d: %s", keyNum);
+        }
+        if (fits_get_keytype(keyValue, &keyType, &status) != 0) {
+            fits_get_errstatus(status, fitsErr);
+            if (status != VALUE_UNDEFINED) {
+                FITS_ERROR("FITS error while determining key %d type: %s", keyNum);
+            } else {
+                // Some keywords are still valid if they don't have a type (like COMMENTS and HISTORY)
+                keyType = 'C';
+                status = 0;
+            }
+        }
+
+        switch (keyType) {
+        case 'I':
+            metadataItemType = PS_META_S32;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, metadataItemType, keyComment, atoi(keyValue));
+            break;
+        case 'F':
+            metadataItemType = PS_META_F64;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, metadataItemType, keyComment, atof(keyValue));
+            break;
+        case 'C':
+            metadataItemType = PS_META_STR;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, metadataItemType, keyComment, keyValue);
+            break;
+        case 'L':
+            metadataItemType = PS_META_BOOL;
+            tempBool = (keyValue[0] == 'T') ? 1 : 0;
+            success = psMetadataAdd(output, PS_LIST_TAIL, keyName, metadataItemType, keyComment, tempBool);
+            break;
+        case 'U':
+        case 'X':
+        default:
+            psError(__func__, "Invalid psMetadataType: %c", keyType);
+            return output;
+        }
+
+        if (!success) {
+            psError(__func__, "Failed to add metadata item. Name: %s", keyName);
+            return output;
+        }
+    }
+
+    return output;
+}
+
+
+int psMetadataParseConfig(psMetadata** md, char *fileName, bool overwrite)
+{
+    bool tempBool;
+    char *line = NULL;
+    char *strName = NULL;
+    char *strType = NULL;
+    char *strValue = NULL;
+    char *strComment = NULL;
+    char *linePtr = NULL;
+    int status = 0;
+    int lineCount = 0;
+    int failedLines = 0;
+    psF64 tempDbl = 0.0;
+    psS32 tempInt = 0.0;
+    psMetadataItem *metadataItem = NULL;
+    psVector *tempVec = NULL;
+    FILE *fp = NULL;
+    psElemType elemType;
+    psMetadataType mdType;
+
+
+    // Check for nulls
+    if(fileName == NULL) {
+        psError(__func__, "Null fileName not allowed");
+        return -1;
+    } else if((fp=fopen(fileName, "r")) == NULL) {
+        psError(__func__, "Couldn't open file. Name: %s", fileName);
+        return -1;
+    }
+
+    // Allocate metadata if necessary
+    if (*md == NULL) {
+        *md = psMetadataAlloc();
+    }
+
+    // Create reusable line for continuous read
+    line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char));
+    if (line == NULL) {
+        psAbort(__func__, "Failed to allocate reusable line");
+    }
+
+    // While loop to parse the file
+    while(fgets(line, MAX_STRING_LENGTH, fp) != NULL) {
+
+        // Initialize variables for new line
+        linePtr = line;
+        lineCount++;
+        CLEAR_TEMPS();
+
+        // If line is not a comment or blank, then extract data
+        if(!ignoreLine(linePtr)) {
+
+            // Check for more than one '*' or '@' in a line
+            if(repeatedChars(linePtr, '@') > 1) {
+                failedLines++;
+                psError(__func__, "More than one @ charecter not allowed. Line %d: %s", lineCount, line);
+                continue;
+            } else if(repeatedChars(linePtr, '*') > 1) {
+                failedLines++;
+                psError(__func__, "More than one * charecter not allowed. Line %d: %s", lineCount, line);
+                continue;
+            } else if(repeatedChars(linePtr, '~') > 0) {
+                failedLines++;
+                psError(__func__, "Illegal character. Character:~ Line %d: %s", lineCount, line);
+                continue;
+            }
+
+            // Get metadata item name
+            strName = getToken(&linePtr, " ", &status);
+            if(strName==NULL || status) {
+                failedLines++;
+                status = 0;
+                psError(__func__, "Null name not allowed. Line %d: %s", lineCount, line);
+                continue;
+            }
+
+            // Get the metadata item type
+            strType = getToken(&linePtr, " ", &status);
+            if(strType==NULL) {
+                failedLines++;
+                status = 0;
+                psError(__func__, "Null type not allowed. Line %d: %s", lineCount, line);
+                continue;
+            } else if(!strncmp(strType, "*", 1)) {
+                mdType = PS_META_ITEM_SET;
+            } else if(!strncmp(strType, "STR", 3)) {
+                mdType = PS_META_STR;
+                elemType = PS_TYPE_PTR;
+            } else if(!strncmp(strType, "BOOL", 3)) {
+                mdType = PS_META_BOOL;
+                elemType = PS_TYPE_U8;
+            } else if(!strncmp(strType, "S32", 3)) {
+                mdType = PS_META_S32;
+                elemType = PS_TYPE_S32;
+            } else if(!strncmp(strType, "F32", 3)) {
+                mdType = PS_META_F32;
+                elemType = PS_TYPE_F32;
+            } else if(!strncmp(strType, "F64", 3)) {
+                mdType = PS_META_F64;
+                elemType = PS_TYPE_F64;
+            } else {
+                failedLines++;
+                psError(__func__, "Invalid psMetadataType. Type: %s Line %d: %s", strType, lineCount, line);
+                continue;
+            }
+
+            if(*strName == '@') {
+                mdType = PS_META_VEC;
+            }
+
+            // Get the metadata item value if there is one. Lines with * don't have values.
+            if(mdType != PS_META_ITEM_SET) {
+                strValue = getToken(&linePtr, "#", &status);
+                if(strValue==NULL) {
+                    failedLines++;
+                    status = 0;
+                    psError(__func__, "Null value not allowed. Line %d: %s", lineCount, line);
+                    continue;
+                }
+            }
+
+            // Get the metadata item value if there is one. Not all lines will have comments, so NULL is ok.
+            strComment = getToken(&linePtr,"~", &status);
+            if(status) {
+                failedLines++;
+                status = 0;
+                psError(__func__, "Failed to parse comment. Line %d: %s", lineCount, line);
+                continue;
+            }
+
+            /* If metadata item is found, is not a folder node, and overwrite is allowed, then remove existing
+            and allow switch/case below to add new item. If overwrite is false, then report error. If found
+            item is folder node, then psMetadataAdd will automatically add a new child. */
+            metadataItem = psMetadataLookup(*md, strName);
+            if(metadataItem != NULL) {
+                if(metadataItem->type!=PS_META_ITEM_SET) {
+                    if(overwrite) {
+                        psMetadataRemove(*md, PS_LIST_UNKNOWN, strName);
+                    } else {
+                        failedLines++;
+                        psError(__func__, "Overwrite for name not allowed. Name: %s. Line %d: %s", strName,
+                                lineCount, line);
+                        continue;
+                    }
+                }
+            }
+
+            // Create and add metadata item to metadata and parse values
+            switch (mdType) {
+            case PS_META_ITEM_SET:
+                psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, NULL, NULL);
+                break;
+            case PS_META_BOOL:
+                tempBool = parseBool(strValue, &status);
+                if(!status) {
+                    psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, strComment, tempBool);
+                } else {
+                    status = 0;
+                    failedLines++;
+                    psError(__func__, "Failed to parse value. Value: %s Line %d: %s", strValue, lineCount, line);
+                    continue;
+                }
+                break;
+            case PS_META_S32:
+                tempInt = (psS32)parseValue(strValue, &status);
+                if(!status) {
+                    psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, strComment, tempInt);
+                } else {
+                    status = 0;
+                    failedLines++;
+                    psError(__func__, "Failed to parse value. Value: %s Line %d: %s", strValue, lineCount, line);
+                    continue;
+                }
+                break;
+            case PS_META_F32:
+            case PS_META_F64:
+                tempDbl = parseValue(strValue, &status);
+                if(!status) {
+                    psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, strComment, tempDbl);
+                } else {
+                    status = 0;
+                    failedLines++;
+                    psError(__func__, "Failed to parse value. Value: %s Line %d: %s", strValue, lineCount, line);
+                    continue;
+                }
+                break;
+            case PS_META_STR:
+                psMetadataAdd(*md, PS_LIST_TAIL, strName, mdType, strComment, strValue);
+                break;
+            case PS_META_VEC:
+                tempVec = parseVector(strValue, elemType, &status);
+                if(!status) {
+                    psMetadataAdd(*md, PS_LIST_TAIL, strName+1, mdType, strComment, tempVec);
+                } else {
+                    status = 0;
+                    failedLines++;
+                    psError(__func__, "Failed to parse value. Value: %s Line %d: %s", strValue, lineCount, line);
+                    continue;
+                }
+                break;
+            default:
+                failedLines++;
+                psError(__func__, "Invalid psMetadataType. Type: %d Line %d: %s", mdType, lineCount, line);
+                continue;
+            } // switch
+        } // if ignoreLine
+    } // while loop
+
+    psFree(line);
+
+    return failedLines;
+}
Index: /branches/rel3/psLib/src/xml/psXML.h
===================================================================
--- /branches/rel3/psLib/src/xml/psXML.h	(revision 2163)
+++ /branches/rel3/psLib/src/xml/psXML.h	(revision 2163)
@@ -0,0 +1,70 @@
+/** @file  psMetadataIO.h
+*
+*  @brief Contains metadata input/output functions.
+*
+*  This file defines functions to read and write metadata to/from an external file.
+*
+*  @ingroup Metadata
+*
+*  @author Ross Harman, MHPCC
+*
+*  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-06 01:17:39 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#ifndef PS_METADATAIO_H
+#define PS_METADATAIO_H
+
+
+/// @addtogroup Metadata
+/// @{
+
+
+/** Print metadata item to file.
+ *
+ *  Metadata items may be printed to an open file descriptor based on a
+ *  provided format. The format is a sprintf format statement with exactly
+ *  one % formatting command. If the metadata item type is a numeric type,
+ *  this formatting command must also be numeric, and the type conversion
+ *  performed to the value to match the format type. If the metadata type is
+ *  a string, the fromatting command must also be for a string. If the
+ *  metadata type is any other data type, printing is not allowed.
+ *
+ * @return psMetadataItem* : Pointer metadata item.
+ */
+void psMetadataItemPrint(
+    FILE * fd,                         ///< Pointer to file to write metadata item.
+    const char *format,                ///< Format to print metadata item.
+    const psMetadataItem* restrict metadataItem ///< Metadata item to print.
+);
+
+/** Read metadata header.
+ *
+ *  Read a metadata header from file. If the file is not found, an error is
+ *  reported.
+ *
+ *  @return psMetadata* : Pointer to resulting metadata.
+ */
+psMetadata* psMetadataReadHeader(
+    psMetadata* output,                ///< Resulting metadata from read.
+    char *extName,                     ///< File name extension string.
+    int extNum,                        ///< File name extension number. Starts at 1.
+    char *fileName                     ///< Name of file to read.
+);
+
+/** Read metadata configuration file.
+ *
+ *  Loads pre-defined settings by parsing a configuration file into a psMetadata structure.
+ *
+ *  @return int : Number of lines that failed to be read.
+ */
+int psMetadataParseConfig(
+    psMetadata** md,                   ///< Resulting metadata from read.
+    char *fileName,                    ///< Name of file to read.
+    bool overwrite                     ///< Allow overwrite of duplicate specifications.
+);
+
+/// @}
+
+#endif
Index: /branches/rel3/psLib/test/.cvsignore
===================================================================
--- /branches/rel3/psLib/test/.cvsignore	(revision 2163)
+++ /branches/rel3/psLib/test/.cvsignore	(revision 2163)
@@ -0,0 +1,3 @@
+temp
+tst_psTime_01
+tst_psTime_02
Index: /branches/rel3/psLib/test/FullUnitTest
===================================================================
--- /branches/rel3/psLib/test/FullUnitTest	(revision 2163)
+++ /branches/rel3/psLib/test/FullUnitTest	(revision 2163)
@@ -0,0 +1,710 @@
+#!/usr/bin/perl
+#
+#  This is a perl script test harness which will recursively search the
+#  directory tree looking for files named UnitTest and then execute
+#  the script
+#
+#  SYNOSIS :  FullUnitTest options arguements
+#
+#       where  options =
+#             --verbose     Display extra information to user
+#             --noverbose   Don't display extra information to user
+#             --recursiv e  Recursively run tests in directory tree
+#             --norecursive Test only the specified or current directory
+#             --silent      Don't display any information to user
+#             --nosilent    Display progress of script to user
+#
+#              arguements = directory(ies) to perform tests
+#
+#  RETURN : integer number of tests which failed
+#
+#  $Revision: 1.14 $  $Name: not supported by cvs2svn $
+#  $Date: 2004-08-20 00:51:22 $
+#
+#  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+#
+##############################################################################
+
+# Provide functions for determining the pathname of current working directory
+use Cwd;
+
+# Provides functions for handling long command line options
+use Getopt::Long;
+
+# Assign variables based on the presence of command line options to the script
+# The ! option allows for --nooption to be set to zero
+# (e.g. --noverbose --recursive causes $verbose=0 and $recursive=1)
+GetOptions(
+    "verbose!"   => \$verbose,
+    "recursive!" => \$recursive,
+    "silent!"    => \$silent,
+    "clean!"     => \$clean
+);
+
+# Check if both silent and verbose options are set and if so stop the script
+die "Can't specify both verbose and silent options." if ( $verbose && $silent );
+
+# Set up the PSLIB_ROOT environment variable if the user doesn't have
+if ( !$ENV{'PSLIB_ROOT'} ) {
+
+    # Use the directory directly above where FullUnitTest script resides
+    $PSLIB_ROOT = `cd ..;pwd`;
+
+    # Remove newline for the end of path returned
+    chomp($PSLIB_ROOT);
+
+    # Set the environment variable
+    $ENV{'PSLIB_ROOT'} = $PSLIB_ROOT;
+    print("PSLIB_ROOT not found: set to $PSLIB_ROOT.\n") if $verbose;
+}
+
+# add PSLIB_ROOT/lib to LD_LIBRARY_PATH and DYLD_LIBRARY_PATH environment
+# variables
+$ENV{'LD_LIBRARY_PATH'}   = "$ENV{'PSLIB_ROOT'}/lib:$ENV{'LD_LIBRARY_PATH'}";
+$ENV{'DYLD_LIBRARY_PATH'} = "$ENV{'PSLIB_ROOT'}/lib:$ENV{'DYLD_LIBRARY_PATH'}";
+
+# Initialize variables for counting the makes and test failures and the
+# total makes and tests performed
+$makeFailCount       = 0;
+$testpointFailCount  = 0;
+$testDriverFailCount = 0;
+$totalTestpoints     = 0;
+$totalTestDrivers    = 0;
+$totalMakes          = 0;
+
+# Initialize variable indicating how many arguements were passed
+$args = 0;
+
+# Loop through all the arguements passed to the script
+foreach (@ARGV) {
+
+    # Remove newline if there is one
+    chomp;
+
+    # Increment number of arguements found
+    $args++;
+
+    # Set variable to current working directory
+    $cwd = cwd;
+
+    # Change directory to the directory of the arguement
+    chdir($_);
+
+    # Check for the recursive option
+    if ($recursive) {
+
+        # Invoke subroutine to go to the lowest directory in tree
+        # starting at the specified directory
+        &worm($_);
+    }
+    else {
+
+        # Invoke subroutines to run the test at the specified directory
+        &makeTestDrivers($_);
+        &executeTestDrivers($_);
+    }
+
+    # Change directory back to the directory where FullUnitTest was invoked
+    chdir($cwd);
+}
+
+# Check if there were no arguements specified
+if ( $args == 0 ) {
+
+    # Display message to user that all directories under the current will be
+    # tested
+    print("Recursively testing current directory tree.\n") if $verbose;
+
+    # Invoke subroutine to go to recursively test each directory in tree
+    &worm( $ENV{"PWD"} );
+}
+
+# Check if there were any failures during make or testing
+if ( $makeFailCount > 0 || $testDriverFailCount > 0 ) {
+
+    # Display summary of failures
+    print("\nMake Failures = $makeFailCount out of $totalMakes");
+    print(
+"\nTest Driver Failures = $testDriverFailCount out of $totalTestDrivers\n"
+    );
+    print( "\nMakes that failed:\n  " . join( "\n  ", @makesFailed ) . "\n" )
+      if $makeFailCount;
+    print( "\nTests that failed:\n  " . join( "\n  ", @testsFailed ) . "\n" )
+      if $testDriverFailCount;
+}
+else {
+
+    # Display message of all makes and tests pass to user if silent option
+    # not specified
+    print(
+"\nAll $totalTestDrivers Test Drivers Passed with $totalTestpoints Testpoints.\n"
+      )
+      if ( !$silent );
+}
+
+# Exit with the number of tests that failed
+exit($testDriverFailCount);
+
+################################################################################
+#
+# SUBROUTINE: worm
+#
+#     Description:  This subroutine will perform the necessary unit tests be
+#                   calling makeTestDrivers and executeTestDrivers  subroutines
+#                   and then check each subdirectory below the base directory
+#                   recursively.
+#
+#     Parameter(s):  base directory to start testing
+#
+#     Return:  None
+#
+################################################################################
+
+sub worm {
+
+    # Assign local variable to input parameter
+    local ($base_dir) = @_;
+    local ( @files, $i );
+
+    # Invoke subroutine to make test driver in the base directory
+    &makeTestDrivers($base_dir);
+
+    # Invoke subroutine to execute tests in the base directory
+    &executeTestDrivers($base_dir);
+
+    # Create array of entries found in directory
+    @files = <*>;
+
+    # Loop through the file list looking for another directory that is not
+    # labelled CVS and recursively invoke subroutine worm
+    $i = 0;
+    while ( $files[$i] ) {
+
+        # Check for directory and directory not labelled CVS
+        if (   -d $files[$i]
+            && ( $files[$i] ne "CVS" )
+            && ( $files[$i] ne "temp" )
+            && ( $files[$i] ne "verified" ) )
+        {
+
+            # Change current directory to directory found
+            chdir( $files[$i] );
+
+            # Invoke subroutine worm again
+            &worm( $files[$i] );
+
+            # Change current directory back to parent
+            chdir("..");
+        }
+
+        # Increment file list index
+        $i++;
+    }
+}
+
+################################################################################
+#
+#  SUBROUTINE: makeTestDrivers
+#
+#      Description:  This subroutine will perform a make for all the necessary
+#                    test drivers.    This will occur in the specified
+#                    base directory which is passed as the only parameter.
+#
+#      Parameter(s):  base directory where make and test drivers are located
+#
+#      Return:  None
+#
+################################################################################
+
+sub makeTestDrivers {
+    local ($base_dir) = @_;
+    local ($pwd);
+
+    # Set variable pwd to current working directory
+    $pwd = cwd;
+
+    # Display message to user in which directory testing is taken place only
+    # if the silent command option was not specified
+    print("---- Entering $pwd ----\n") if ( !$silent );
+
+    # Check for the existence of a file name Makefile in current directory
+    if ( -e "Makefile" ) {
+
+        # Increment the total number of makes executed
+        $totalMakes++;
+
+        if ($clean) {
+
+            # Execute the make clean
+            `make clean`;
+
+            # Execute the make distclean
+            `make distclean`;
+        }
+
+        # Execute the make and save results
+        $_ = join( "\n|| ", split( "\n", "\n" . `make` ) );
+
+        # Check the output of make for return value != 0 or any of the
+        # following words: FAILED, FAULT, ERROR, Not found, SIGNAL
+        if (   ( $? != 0 )
+            || m/FAILED/i
+            || m/FAULT/i
+            || m/\bERROR/i
+            || m/Not found/i
+            || m/SIGNAL/i )
+        {
+
+            # Display the errored output of make if silent option not enabled
+            print("$_\n") if ( !$silent );
+
+            # Display the make failed in the current directory
+            print("\nMake for $pwd Failed\n");
+
+            # Increment the number of makes that have failed
+            $makeFailCount++;
+
+            # Push the current working directory onto the list of failed
+            # make directories list
+            push( @makesFailed, $pwd );
+        }
+        else {
+
+            # Display the results of the successful make if verbose option set
+            print("$_\n") if $verbose;
+
+            # Display the make was successful if silent option not set
+            print("\nMake successful.\n") if ( !$silent );
+            if ($clean) {
+                `make install`;
+            }
+        }
+    }
+}
+
+################################################################################
+#
+#  SUBROUTINE: executeTestDrivers
+#
+#      Description:  This subroutine will execute all the necessary
+#                    test drivers.    This will occur in the specified
+#                    base directory which is passed as the only parameter.
+#
+#      Parameter(s):  base directory where make and test drivers are located
+#
+################################################################################
+
+sub executeTestDrivers {
+    local ($base_dir) = @_;
+    local ( @files, $j );
+    local ($pwd);
+    local ($exitValue) = 0;
+
+    # Set variable to pwd to current test directory
+    $pwd = cwd;
+
+    # Create a list of all elements in base directory
+    @files = <*>;
+
+    # Loop through all the items in the files array
+    $initialTest = 0;
+    $j           = 0;
+    while ( $files[$j] ) {
+
+        # Check that the item is not a directory and is executable and
+        # conforms to the test driver naming convention TST
+        if (   !( -d $files[$j] )
+            && ( -x $files[$j] )
+            && ( $files[$j] =~ /^TST/i || $files[$j] =~ /^ATST/i ) )
+        {
+
+            # Increment total number of test drivers executed
+            $totalTestDrivers++;
+
+            # Perform subdirectory checks only the first time a test
+            # file is found with the list of enteries
+            if ( $initialTest == 0 ) {
+                $initialTest++;
+
+                # Check for a temp subdirectory already exists and if not
+                # then create one
+                &checkForTempDirectory();
+
+                # Check for the presence of verified directory
+                if ( &checkForVerifiedDirectory() ) {
+
+    # Display message to user that verified directories do not
+    # exist eventhough TST files have been found
+    #                    print("Unable to execute test drivers in $base_dir\n");
+                    print("No verified subdirectory present.\n") if ($verbose);
+
+               # Increment test fail count
+               #                   $testDriverFailCount++;
+               # Save the file failed
+               #                    push(@testsFailed, $pwd . "/" . $files[$j]);
+               #                    return;
+                }
+            }
+
+            # Display message to user of which test driver is being executed
+            print("--- Executing test driver $files[$j]\n") if ( !$silent );
+
+            # Execute the test driver
+            system(
+"./$files[$j] 1> temp/$files[$j].stdout 2> temp/$files[$j].stderr"
+            );
+            $retVal = $?;
+
+            # Count testpoints
+            $testPattern = "\"\\*\\*\\*\\* TESTPOINT \\*\\*\\*\\*\"";
+            $totalPoints = `grep -c $testPattern temp/$files[$j].stdout`;
+            $totalPoints += `grep -c $testPattern temp/$files[$j].stderr`;
+            $failPoints =
+              `grep "> TESTPOINT FAILED" temp/$files[$j].stdout | wc -l`;
+            $failPoints +=
+              `grep "> TESTPOINT FAILED" temp/$files[$j].stderr | wc -l`;
+            $testpointFailCount += $failPoints;
+            $totalTestpoints    += $totalPoints;
+
+            # Check result of test driver
+            if (   ( ( $retVal != 0 ) && ( $files[$j] =~ /^TST/i ) )
+                || ( ( $retVal == 0 ) && ( $files[$j] =~ /^ATST/i ) ) )
+            {
+
+                # Display test driver failed
+                $failPoints++;
+                print(
+                    "Test driver: $files[$j] Failed (Return value $retVal).\n");
+
+                # Increment the total number of test failed
+                $testDriverFailCount++;
+
+                # Push the current working directory on the list of failed
+                push( @testsFailed, $pwd . "/" . $files[$j] );
+            }
+            else {
+
+               # Create filter versions of STDOUT and STDERR to replace variable
+               # items such as date, time and host
+                &filterStdFiles( $files[$j] );
+
+                # Perform difference on STDOUT file collected
+                # with verified files
+                $exitValue = &compareStream("verified/$files[$j].stdout");
+                if ( $exitValue & 2 ) {
+
+                    # STDOUT verified doesn't exist. Search STDOUT capture
+                    # for strings indicating error or failure
+                    $exitValue |= &errorStrSearch("$files[$j].stdout");
+                }
+                if ( ( $exitValue & 8 ) || ( $exitValue & 64 ) ) {
+
+                    # Increment the total number of test failed
+                    $testDriverFailCount++;
+
+                    # Push test on failed list
+                    print(
+"Test failed ($failPoints out of $totalPoints testpoints failed)\n"
+                      )
+                      if ( !$silent );
+                    push( @testsFailed, $pwd . "/" . $files[$j] );
+                }
+                else {
+
+                    # Perform difference on STDERR file collection with verified
+                    $exitValue = &compareStream("verified/$files[$j].stderr");
+                    if ( $exitValue & 4 ) {
+
+                        # STDERR verified doesn't exist. Search STDERR capture
+                        # for strings indicating error or failure
+                        $exitValue |= &errorStrSearch("$files[$j].stderr");
+                    }
+                    if ( ( $exitValue & 16 ) || ( $exitValue & 128 ) ) {
+
+                        # Increment the total number of tests failed
+                        $testDriverFailCount++;
+
+                        # Push test on failed list
+                        print(
+"Test failed ($failPoints out of $totalPoints testpoints failed)\n"
+                          )
+                          if ( !$silent );
+                        push( @testsFailed, $pwd . "/" . $files[$j] );
+                    }
+                    else {
+                        print("Test successful ($totalPoints testpoints)\n")
+                          if ( !$silent );
+                    }
+                }
+            }
+        }
+        $j++;
+    }
+}
+
+################################################################################
+#
+#  SUBROUTINE: errorStrSearch
+#
+#      Description:  This subroutine will search the file specified in its
+#                    parameter for error strings and if they do exists
+#                    the appropriate value will be returned.
+#
+#      Parameter(s): fileName - input file to search for strings
+#
+#      Return:   0  -  No error strings found
+#               64  -  Error strings found in STDOUT
+#              128  -  Error strings found in STDERR
+#
+###############################################################################
+
+sub errorStrSearch {
+    local ($fileName)  = @_;
+    local ($returnVal) = 0;
+
+    # Open the captured file
+    open( CAPT_FILE, "<temp/$fileName" );
+
+    # Scan through all the lines of the file searching for error strings
+    while (<CAPT_FILE>) {
+        if (   m/FAIL/i
+            || m/FAULT/i
+            || m/ERROR/i
+            || m/Not Found/i
+            || m/SIGNAL/i
+            || m/NO SUCH FILE/i
+            || m/\|E\|/i
+            || m/\|A\|/i )
+        {
+            print;
+            if ( $fileName =~ m/out/ ) {
+                print(
+                    "        Failed - File $fileName contains error strings.\n"
+                );
+                $returnVal = 64;
+            }
+            elsif ( $fileName =~ m/err/ ) {
+                print(
+                    "        Failed - File $fileName contains error strings.\n"
+                );
+                $returnVal = 128;
+            }
+            last;
+        }
+    }
+
+    # Close the capture file
+    close(CAPT_FILE);
+
+    # Return the return value
+    return ($returnVal);
+}
+
+################################################################################
+#
+#  SUBROUTINE: compareStream
+#
+#      Description:  This subroutine will compare the captured stream file with
+#                    a file in the verified directory if one exists.
+#
+#      Parameter(s): streamFile - input file to compare
+#
+#      Return:   0  -  Compare successful
+#                2  -  STDOUT verified file doesn't exist
+#                4  -  STDERR verified file doesn't exist
+#                8  -  STDOUT verified file doesn't compare
+#               16  -  STDERR verified file doesn't compare
+#
+###############################################################################
+
+sub compareStream {
+    local ($streamFile) = @_;
+    local ($returnVal)  = 0;
+    local ($tempFile)   = "";
+
+    # Check for existence of verified STD stream files
+    if ( !( -e $streamFile ) ) {
+
+        # Display message to user that verified STDOUT file doesn't exist
+        print("        File $streamFile doesn't exist.\n") if ($verbose);
+
+        # Set exit value bit 1 to indicate proper failure
+        if ( $streamFile =~ /out$/ ) {
+            $returnVal |= 2;
+        }
+        elsif ( $streamFile =~ /err$/ ) {
+            $returnVal |= 4;
+        }
+    }
+    else {
+
+        # Verified STD stream file exists
+
+        # Create name of the temp file to compare
+        $tempFile = $streamFile;
+        $tempFile =~ s/verified/temp/;
+        $tempFile = $tempFile . ".mod";
+
+        # Perform difference on the STD stream files
+        $diffstdout = `diff $streamFile $tempFile`;
+
+        # Check the return value of the difference
+        if ( $? != 0 ) {
+
+            # Difference of STD stream files failed
+
+            # Check for STDOUT in file name to convey appropirate return value
+            if ( $streamFile =~ /out$/ ) {
+
+                # Display message of the failure of difference to user
+                print("        Failed - STDOUT difference\n$diffstdout\n");
+
+                # Exit value to indicate STDOUT did not compare
+                $returnVal |= 8;
+            }
+            elsif ( $streamFile =~ /err$/ ) {
+
+                # Display message of the failure of difference to user
+                print("        Failed - STDERR difference\n$diffstdout\n");
+
+                # Exit value to indicate STDERR did not compare
+                $returnVal |= 16;
+            }
+        }
+    }
+
+    # Return the result of the compare
+    return ($returnVal);
+}
+
+################################################################################
+#
+#  SUBROUTINE: checkForTempDirectory
+#
+#      Description:  This subroutine will check for the existence of a temp
+#                    directory to store STDOUT, STDERR files during test.  If
+#                    the subdirectory doesn't exist, it will be created.
+#
+#      Parameter(s):  None
+#
+#      Return: None
+#
+################################################################################
+
+sub checkForTempDirectory {
+
+    # Check if a temp directory already exists in the current work directory
+    if ( !( -e "temp" ) ) {
+
+        # Create temp directory to store STDOUT, STDERR files during test
+        `mkdir temp`;
+
+        # Display message of new directory created
+        print("Creating temp directory\n") if ($verbose);
+    }
+}
+
+################################################################################
+#
+#  SUBROUTINE: checkForVerifiedDirectory
+#
+#      Description:  This subroutine will check for the existence of a verified
+#                    directory which stores verified STDOUT, STDERR files for
+#                    comparison during the test.
+#
+#      Parameter(s):  None
+#
+#      Return: 0 - subdirectory present
+#              1 - subdirectory not present
+#
+################################################################################
+
+sub checkForVerifiedDirectory {
+    $returnValue = 0;
+
+    # Check if verified subdirectory exists in the current working directory
+    if ( !( -e "verified" ) ) {
+
+        # Set return value to 1
+        $returnValue = 1;
+    }
+    return ($returnValue);
+}
+
+################################################################################
+#
+#  SUBROUTINE: filterStdFiles
+#
+#      Description:  This subroutine will filter variable items in the STDOUT
+#                    and STDERR files captured.  Date, time and host names
+#                    are variable items in the log messages captured.
+#
+#      Parameter(s):  test file name
+#
+#      Return: None
+#
+################################################################################
+
+sub filterStdFiles {
+
+    local ($fileName) = @_;
+
+    # Open the STDOUT file for reading
+    open( OUTFILE, "< temp/$fileName.stdout" );
+
+    # Open mod file to place filtered STDOUT
+    open( MODFILE, "> temp/$fileName.stdout.mod" );
+
+    # Replace the variable data, time and host information with constants
+    $hostname = `hostname`;
+    chop $hostname;
+    while (<OUTFILE>) {
+        s/\s+\d+:\d+:\d+\w/<TIME>/g;
+        s/\d+:\d+:\d+/<DATE>/g;
+        s/$hostname\s*/<HOST>/g;
+        s/: Line \d+/: Line <LINENO>/g;
+        s/\:\d+/\:<LINENO>/g;
+        s/allocate \d+ bytes at/allocate <N> bytes at/g;
+
+        # Filter lines with *** malloc.  This is an artifact of Mac testing of
+        # memory functions
+        if ( !m/\*\*\*\smalloc/ ) {
+            print MODFILE ($_);
+        }
+    }
+
+    # Close mod file
+    close(MODFILE);
+
+    # Close STDERR file
+    close(OUTFILE);
+
+    # Open the STDERR file for reading
+    open( OUTFILE, "< temp/$fileName.stderr" );
+
+    # Open mod file to place filtered STDERR
+    open( MODFILE, "> temp/$fileName.stderr.mod" );
+
+    # Replace the variable date, time and host information with constants
+    while (<OUTFILE>) {
+        s/\s+\d+:\d+:\d+\w/<TIME>/g;
+        s/\d+:\d+:\d+/<DATE>/g;
+        s/$hostname\s*/<HOST>/g;
+        s/: Line \d+/: Line <LINENO>/g;
+        s/\:\d+/\:<LINENO>/g;
+        s/allocate \d+ bytes at/allocate <N> bytes at/g;
+
+        # Filter lines with *** malloc.  This is an artifact of Mac testing of
+        # memory functions
+        if ( !m/\*\*\*\smalloc/ ) {
+            print MODFILE ($_);
+        }
+    }
+
+    # Close mod file
+    close(MODFILE);
+
+    # Close STDERR file
+    close(OUTFILE);
+}
+
Index: /branches/rel3/psLib/test/Makefile
===================================================================
--- /branches/rel3/psLib/test/Makefile	(revision 2163)
+++ /branches/rel3/psLib/test/Makefile	(revision 2163)
@@ -0,0 +1,101 @@
+##############################################################################
+##
+##  Makefile:   test
+##
+##  $Revision: 1.9 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-10-15 19:14:11 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+###############################################################################
+
+# Define variable prefix to the top level project - psLib
+# This is necessary for definition is Makefile.Globals uses prefix
+
+ifndef prefix
+    export prefix=$(shell cd ..;pwd)
+endif
+
+# Define the two targets to be built
+
+TARGET_STATIC  = libpstest.a
+TARGET_DYNAMIC = libpstest.$(DLL)
+
+# Include the make global definitions for the project
+
+include ../src/Makefile.Globals
+
+# Set CFLAGS used by the implicit rule to compile .c
+
+CFLAGS := $(CFLAGS_RELOC) -I../include
+
+# Define the source objects
+ 
+SRC_OBJS = psTest.o
+
+# Define PHONY target "all" which will make all the necessary items
+
+all: $(TARGET_STATIC) $(TARGET_DYNAMIC)
+
+# Rule to make static library
+
+libpstest.a: $(SRC_OBJS)
+# The ar option -r is to add/replace object and -s is to create
+# a symbol table in the archive
+	$(AR) rcs $@ $(SRC_OBJS)
+
+# Rule to make dynamic library
+
+libpstest.$(DLL): $(SRC_OBJS)
+	$(CC) $(LDFLAGS_DLL) -L../lib -lpslib $(SRC_OBJS) -o $@  
+
+# Define PHONY target "install" which will install necessary files
+
+install: $(TARGET_STATIC) $(TARGET_DYNAMIC) $(includedir) $(libexecdir) $(testbindir)
+	install *.h $(includedir)
+	install $(TARGET_STATIC) $(libexecdir)
+	install $(TARGET_DYNAMIC) $(libexecdir)
+	install FullUnitTest runTest $(testbindir)
+	$(MAKE) --directory=collections install
+	$(MAKE) --directory=image install
+	$(MAKE) --directory=dataManip install
+	$(MAKE) --directory=sysUtils install
+	$(MAKE) --directory=astronomy install
+
+# Define PHONY target "distclean" which will cleanup the distribution
+
+distclean:	clean
+	$(MAKE) --directory=collections distclean
+	$(MAKE) --directory=image distclean
+	$(MAKE) --directory=dataManip distclean
+	$(MAKE) --directory=sysUtils distclean
+	$(RM) $(TARGET_STATIC)
+	$(RM) $(TARGET_DYNAMIC)
+	$(RM) $(libexecdir)/$(TARGET_STATIC)
+	$(RM) $(libexecdir)/$(TARGET_DYNAMIC)
+
+# Define PHONY target "clean" which will cleanup the development area
+
+clean:
+	$(MAKE) --directory=collections clean
+	$(MAKE) --directory=image clean
+	$(MAKE) --directory=dataManip clean
+	$(MAKE) --directory=sysUtils clean
+	@echo "    Deleting intermediate files for 'test'"
+	$(RM) $(SRC_OBJS) *.lint
+
+%.lint: %.c
+	splint +posixlib -exportlocal -realcompare $(INCLUDE_GLOBAL) $? > $@; cat $@
+
+# Rule to make include directory if needed
+
+$(includedir):
+	mkdir -p $(includedir)
+
+# Rule to make lib directory if needed
+
+$(libexecdir):
+	mkdir -p $(libexecdir)
+
+$(testbindir):
+	mkdir -p $(testbindir)
+
Index: /branches/rel3/psLib/test/astronomy/.cvsignore
===================================================================
--- /branches/rel3/psLib/test/astronomy/.cvsignore	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/.cvsignore	(revision 2163)
@@ -0,0 +1,14 @@
+temp
+tst_psTime_01
+tst_psTime_02
+tst_psMetadata05_OUT
+tst_psMetadata_01
+tst_psMetadata_02
+tst_psMetadata_03
+tst_psMetadata_04
+tst_psMetadata_05
+tst_psMetadata_06
+tst_psAstrometry
+tst_psAstrometry01
+tst_psCoord
+tst_psMetadataIO
Index: /branches/rel3/psLib/test/astronomy/Makefile
===================================================================
--- /branches/rel3/psLib/test/astronomy/Makefile	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/Makefile	(revision 2163)
@@ -0,0 +1,54 @@
+################################################################################
+##
+##  Makefile:   test/astronomy
+##
+##  $Revision: 1.20 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-10-15 19:10:51 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+##
+###############################################################################
+
+ifndef prefix
+    export prefix=$(shell cd ../..;pwd)
+endif
+
+include ../../src/Makefile.Globals
+
+CFLAGS := -I../../include $(CFLAGS)
+LDFLAGS := -L../../lib -lpslib -lpstest $(LDFLAGS)
+
+TARGET = tst_psTime_01 \
+         tst_psTime_02 \
+         tst_psMetadataIO  \
+         tst_psMetadata_01 \
+         tst_psMetadata_02 \
+         tst_psMetadata_03 \
+         tst_psMetadata_04 \
+         tst_psMetadata_05 \
+         tst_psMetadata_06 \
+         tst_psCoord \
+         tst_psAstrometry \
+         tst_psAstrometry01
+
+OBJS = $(addprefix builddir/,$(addsuffix .o,$(TARGET)))
+
+all: $(TARGET)
+
+clean:
+	@echo "    Deleting executable and binary files for 'test/collections'"
+	$(RM) $(OBJS)
+
+distclean: clean
+	$(RM) $(TARGET)
+
+install: $(testbindir) $(testbindir)/verified $(TARGET)
+	install test.config header_1.fits header_2.fits $(TARGET) $(testbindir)
+	install verified/*.stderr verified/*.stdout $(testbindir)/verified
+
+$(testbindir):
+	mkdir -p $(testbindir)
+
+$(testbindir)/verified:
+	mkdir -p $(testbindir)/verified
+
Index: /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_01.d
===================================================================
--- /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_01.d	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_01.d	(revision 2163)
@@ -0,0 +1,15 @@
+builddir/tst_psMetadata_01.o: tst_psMetadata_01.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psCompare.h ../../include/psArray.h \
+  ../../include/psHash.h ../../include/psScalar.h \
+  ../../include/psVector.h ../../include/psImage.h \
+  ../../include/psImageExtraction.h ../../include/psStats.h \
+  ../../include/psImageManip.h ../../include/psImageIO.h \
+  ../../include/psImageStats.h ../../include/psFunctions.h \
+  ../../include/psBitSet.h ../../include/psMatrix.h \
+  ../../include/psMatrixVectorArithmetic.h ../../include/psFFT.h \
+  ../../include/psMinimize.h ../../include/psCoord.h \
+  ../../include/psTime.h ../../include/psPhotometry.h \
+  ../../include/psMetadata.h ../../include/psTest.h
Index: /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_02.d
===================================================================
--- /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_02.d	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_02.d	(revision 2163)
@@ -0,0 +1,15 @@
+builddir/tst_psMetadata_02.o: tst_psMetadata_02.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psCompare.h ../../include/psArray.h \
+  ../../include/psHash.h ../../include/psScalar.h \
+  ../../include/psVector.h ../../include/psImage.h \
+  ../../include/psImageExtraction.h ../../include/psStats.h \
+  ../../include/psImageManip.h ../../include/psImageIO.h \
+  ../../include/psImageStats.h ../../include/psFunctions.h \
+  ../../include/psBitSet.h ../../include/psMatrix.h \
+  ../../include/psMatrixVectorArithmetic.h ../../include/psFFT.h \
+  ../../include/psMinimize.h ../../include/psCoord.h \
+  ../../include/psTime.h ../../include/psPhotometry.h \
+  ../../include/psMetadata.h ../../include/psTest.h
Index: /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_03.d
===================================================================
--- /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_03.d	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_03.d	(revision 2163)
@@ -0,0 +1,15 @@
+builddir/tst_psMetadata_03.o: tst_psMetadata_03.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psCompare.h ../../include/psArray.h \
+  ../../include/psHash.h ../../include/psScalar.h \
+  ../../include/psVector.h ../../include/psImage.h \
+  ../../include/psImageExtraction.h ../../include/psStats.h \
+  ../../include/psImageManip.h ../../include/psImageIO.h \
+  ../../include/psImageStats.h ../../include/psFunctions.h \
+  ../../include/psBitSet.h ../../include/psMatrix.h \
+  ../../include/psMatrixVectorArithmetic.h ../../include/psFFT.h \
+  ../../include/psMinimize.h ../../include/psCoord.h \
+  ../../include/psTime.h ../../include/psPhotometry.h \
+  ../../include/psMetadata.h ../../include/psTest.h
Index: /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_04.d
===================================================================
--- /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_04.d	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_04.d	(revision 2163)
@@ -0,0 +1,15 @@
+builddir/tst_psMetadata_04.o: tst_psMetadata_04.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psCompare.h ../../include/psArray.h \
+  ../../include/psHash.h ../../include/psScalar.h \
+  ../../include/psVector.h ../../include/psImage.h \
+  ../../include/psImageExtraction.h ../../include/psStats.h \
+  ../../include/psImageManip.h ../../include/psImageIO.h \
+  ../../include/psImageStats.h ../../include/psFunctions.h \
+  ../../include/psBitSet.h ../../include/psMatrix.h \
+  ../../include/psMatrixVectorArithmetic.h ../../include/psFFT.h \
+  ../../include/psMinimize.h ../../include/psCoord.h \
+  ../../include/psTime.h ../../include/psPhotometry.h \
+  ../../include/psMetadata.h ../../include/psTest.h
Index: /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_05.d
===================================================================
--- /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_05.d	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_05.d	(revision 2163)
@@ -0,0 +1,15 @@
+builddir/tst_psMetadata_05.o: tst_psMetadata_05.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psCompare.h ../../include/psArray.h \
+  ../../include/psHash.h ../../include/psScalar.h \
+  ../../include/psVector.h ../../include/psImage.h \
+  ../../include/psImageExtraction.h ../../include/psStats.h \
+  ../../include/psImageManip.h ../../include/psImageIO.h \
+  ../../include/psImageStats.h ../../include/psFunctions.h \
+  ../../include/psBitSet.h ../../include/psMatrix.h \
+  ../../include/psMatrixVectorArithmetic.h ../../include/psFFT.h \
+  ../../include/psMinimize.h ../../include/psCoord.h \
+  ../../include/psTime.h ../../include/psPhotometry.h \
+  ../../include/psMetadata.h ../../include/psTest.h
Index: /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_06.d
===================================================================
--- /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_06.d	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/builddir/tst_psMetadata_06.d	(revision 2163)
@@ -0,0 +1,15 @@
+builddir/tst_psMetadata_06.o: tst_psMetadata_06.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psCompare.h ../../include/psArray.h \
+  ../../include/psHash.h ../../include/psScalar.h \
+  ../../include/psVector.h ../../include/psImage.h \
+  ../../include/psImageExtraction.h ../../include/psStats.h \
+  ../../include/psImageManip.h ../../include/psImageIO.h \
+  ../../include/psImageStats.h ../../include/psFunctions.h \
+  ../../include/psBitSet.h ../../include/psMatrix.h \
+  ../../include/psMatrixVectorArithmetic.h ../../include/psFFT.h \
+  ../../include/psMinimize.h ../../include/psCoord.h \
+  ../../include/psTime.h ../../include/psPhotometry.h \
+  ../../include/psMetadata.h ../../include/psTest.h
Index: /branches/rel3/psLib/test/astronomy/builddir/tst_psTime_01.d
===================================================================
--- /branches/rel3/psLib/test/astronomy/builddir/tst_psTime_01.d	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/builddir/tst_psTime_01.d	(revision 2163)
@@ -0,0 +1,15 @@
+builddir/tst_psTime_01.o: tst_psTime_01.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psCompare.h ../../include/psArray.h \
+  ../../include/psHash.h ../../include/psScalar.h \
+  ../../include/psVector.h ../../include/psImage.h \
+  ../../include/psImageExtraction.h ../../include/psStats.h \
+  ../../include/psImageManip.h ../../include/psImageIO.h \
+  ../../include/psImageStats.h ../../include/psFunctions.h \
+  ../../include/psBitSet.h ../../include/psMatrix.h \
+  ../../include/psMatrixVectorArithmetic.h ../../include/psFFT.h \
+  ../../include/psMinimize.h ../../include/psCoord.h \
+  ../../include/psTime.h ../../include/psPhotometry.h \
+  ../../include/psMetadata.h ../../include/psTest.h
Index: /branches/rel3/psLib/test/astronomy/builddir/tst_psTime_02.d
===================================================================
--- /branches/rel3/psLib/test/astronomy/builddir/tst_psTime_02.d	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/builddir/tst_psTime_02.d	(revision 2163)
@@ -0,0 +1,15 @@
+builddir/tst_psTime_02.o: tst_psTime_02.c ../../include/pslib.h \
+  ../../include/psMemory.h ../../include/psLogMsg.h \
+  ../../include/psTrace.h ../../include/psAbort.h ../../include/psError.h \
+  ../../include/psString.h ../../include/psType.h ../../include/psList.h \
+  ../../include/psCompare.h ../../include/psArray.h \
+  ../../include/psHash.h ../../include/psScalar.h \
+  ../../include/psVector.h ../../include/psImage.h \
+  ../../include/psImageExtraction.h ../../include/psStats.h \
+  ../../include/psImageManip.h ../../include/psImageIO.h \
+  ../../include/psImageStats.h ../../include/psFunctions.h \
+  ../../include/psBitSet.h ../../include/psMatrix.h \
+  ../../include/psMatrixVectorArithmetic.h ../../include/psFFT.h \
+  ../../include/psMinimize.h ../../include/psCoord.h \
+  ../../include/psTime.h ../../include/psPhotometry.h \
+  ../../include/psMetadata.h ../../include/psTest.h
Index: /branches/rel3/psLib/test/astronomy/header_1.fits
===================================================================
--- /branches/rel3/psLib/test/astronomy/header_1.fits	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/header_1.fits	(revision 2163)
@@ -0,0 +1,1 @@
+SIMPLE  =                    T / file does conform to FITS standard             BITPIX  =                    8 / number of bits per data pixel                  NAXIS   =                    0 / number of data axes                            HISTORY File modified by user 'harman' with fv  on 2004-08-04T11:11:18          END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
Index: /branches/rel3/psLib/test/astronomy/header_2.fits
===================================================================
--- /branches/rel3/psLib/test/astronomy/header_2.fits	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/header_2.fits	(revision 2163)
@@ -0,0 +1,1 @@
+SIMPLE  =                    T / file does conform to FITS standard             BITPIX  =                  -64 / number of bits per data pixel                  NAXIS   =                    1 / number of data axes                            NAXIS1  =                   64 / length of data axis 1                          EXTEND  =                    T / FITS dataset may contain extensions            COMMENT   FITS (Flexible Image Transport System) format is defined in 'AstronomyCOMMENT   and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                  -64 / number of bits per data pixel                  NAXIS   =                    1 / number of data axes                            NAXIS1  =                   64 / length of data axis 1                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BITPIX  =                  -64 / number of bits per data pixel                  EXTNAME = 'MY_DATA_1'                                                           HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:14:45          HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:15:29          HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:21:18          HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:21:46          END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                  -64 / number of bits per data pixel                  NAXIS   =                    1 / number of data axes                            NAXIS1  =                   64 / length of data axis 1                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     EXTNAME = 'MY_DATA_2'                                                           HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:22:12          HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:22:52          END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
Index: /branches/rel3/psLib/test/astronomy/test.config
===================================================================
--- /branches/rel3/psLib/test/astronomy/test.config	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/test.config	(revision 2163)
@@ -0,0 +1,129 @@
+##########################################################################################################
+#  test.config
+#
+#  This is a sample metadata configuration file used to test the metadata configuration file parser. 
+#  It tests both positive and negative cases as described in the comments below.
+#
+#  author  Ross Harman, MHPCC
+#
+#  version $Revision: 1.2 $  $Name: not supported by cvs2svn $
+#  date  $Date: 2004-10-06 22:51:52 $
+#
+#  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+##########################################################################################################
+#
+#
+#
+########## Test 1 ##########
+# Lines beginning with # are comments. The line below, as well as those above are comments. They should be ignored by the parser.
+# I am a comment.
+#
+#
+#
+########## Test 2 ##########
+# The line below is a comment that begins with some whitespace. It should be ignored by the parser.
+      #        		Another comment
+#
+#
+#
+########## Test 3 ##########
+# The line below is completely blank except for a carriage return. It should be ignored by the parser.
+
+#
+#
+#
+########## Test 4 ##########
+# The line below consists of spaces and tabs (whitespace). It should be ignored by the parser.
+     	   			                    
+#
+#
+#
+########## Test 5 ##########
+# The line below consists of a variable name, type, value, and trailing comment. It should be read by the parser
+pi          F64         3.1415926535897932384626433832795029        # Definition of pi
+#
+#
+#
+########## Test 6 ##########
+# The line below consists of a variable name, type, and value, but without a trailing comment. It should be read by the parser.
+altitude          S32         10000   
+#
+#
+#
+########## Test 7 ##########
+# The lines below contain variations in name, type, value, trailing comment, and whitespace. They should all be read by the parser.
+   time F32 1234.5678 
+ myBool     BOOL            F           # F, f, 0, T, t, 1 are also acceptable
+title1  STR   Hello world #This is a comment for the string value
+    title2  STRING   Good bye world   #    STRING or STR may be used as the string type 
+#
+#
+#
+########## Test 8 ##########
+# The line below creates a vector. It should be read by the parser.
+@primes     S32     2, 3, 5, 7, 11, 13, 17   # These are prime numbers
+#
+#
+#
+########## Test 9 ##########
+# The line below creates a vector with commas mixed with spaces in the values. It should be read by the parser.
+@negatives  S32     -1,  -2 -3    -4, -5, -6,      -7
+#
+#
+#
+########## Test 10  ##########
+# The lines below should create a folder node with children that are strings. They should be read by the parser.
+comment *
+comment STR This
+comment STR     is
+comment STR         an
+comment STR             ugly
+comment STR                 comment
+comment STR                         but
+comment STR                             still
+comment STR                                 valid
+#
+#
+#
+########## Test 11  ##########
+# The line below contains an incorrect value. It should produce an error.
+xPosition    F64          9876.54qqq32
+#
+#
+#
+########## Test 12  ##########
+# The line below contains no value. It should produce an error.
+yPosition    F64          
+#
+#
+#
+########## Test 13  ##########
+# The line below contains no type. It should produce an error.
+zPosition       99.999          
+#
+#
+#
+########## Test 14  ##########
+# The line below contains two * characters. It should produce an error.
+aPosition   **          
+#
+#
+#
+########## Test 15 ##########
+# The line below contains two @ characters. It should produce an error.
+@@bPosition     F64     22.33             
+#
+#
+#
+########## Test 16 ##########
+# The line below contains a ~ character used for special processing. It should produce an error.
+range     F64     140.0 ~             
+#
+#
+#
+########## Test 17 ##########
+# The variable name below is repeated. It should produce an error if the overwrite function argument is set to false.
+# If overwrite is true, then the last name and value will be stored and there will be no error.
+speed     F32     55.55
+speed     F32     66.66
+             
Index: /branches/rel3/psLib/test/astronomy/tst_psAstrometry.c
===================================================================
--- /branches/rel3/psLib/test/astronomy/tst_psAstrometry.c	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/tst_psAstrometry.c	(revision 2163)
@@ -0,0 +1,728 @@
+/** @file  tst_psAstrometry.c
+ *
+ *  @brief Contains the tests for psAstrometry.[ch]
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-13 23:58:20 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <math.h>
+#include <string.h>
+
+#include "psTest.h"
+#include "pslib.h"
+
+static int testExposureAlloc(void);
+static int testObservatoryAlloc(void);
+static int testFPAAlloc(void);
+static int testChipAlloc(void);
+static int testCellAlloc(void);
+static int testReadoutAlloc(void);
+
+testDescription tests[] = {
+                              {testExposureAlloc,735,"psExposureAlloc",0,false},
+                              {testObservatoryAlloc,736,"psObservatoryAlloc",0,false},
+                              {testFPAAlloc,739,"psFPAAlloc",0,false},
+                              {testChipAlloc,740,"psChipAlloc",0,false},
+                              {testCellAlloc,741,"psCellAlloc",0,false},
+                              {testReadoutAlloc,742,"psReadoutAlloc",0,false},
+                              {NULL}
+                          };
+
+int main(int argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    return ! runTestSuite(stderr,"psImage",tests,argc,argv);
+}
+
+static int testExposureAlloc(void)
+{
+    psTime* now = psTimeGetTime(PS_TIME_UTC);
+    char* name = "The Kaiser Royal Observatory";
+
+    psObservatory* obs = psObservatoryAlloc(name,
+                                            20.7, 156.3, 3055.0, 9.0);
+
+    psExposure* exp = psExposureAlloc(1.0, 2.0, 3.0, 4.0, 5.0,
+                                      now, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, obs);
+
+
+    if (fabs(exp->ra - 1.0) > DBL_EPSILON) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psExposureAlloc did not set ra.");
+        return 1;
+    }
+
+    if (fabs(exp->dec - 2.0) > DBL_EPSILON) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psExposureAlloc did not set dec.");
+        return 2;
+    }
+
+    if (fabs(exp->hourAngle - 3.0) > DBL_EPSILON) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psExposureAlloc did not set hourAngle.");
+        return 3;
+    }
+
+    if (fabs(exp->zenithDistance - 4.0) > DBL_EPSILON) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psExposureAlloc did not set zenithDistance.");
+        return 4;
+    }
+
+    if (fabs(exp->azimuth - 5.0) > DBL_EPSILON) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psExposureAlloc did not set azimuth.");
+        return 5;
+    }
+    if (exp->time != now) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psExposureAlloc did not set time.");
+        return 6;
+    }
+
+    if (fabsf(exp->rotAngle - 6.0f) > FLT_EPSILON) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psExposureAlloc did not set rotAngle.");
+        return 7;
+    }
+
+    if (fabsf(exp->temperature - 7.0f) > FLT_EPSILON) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psExposureAlloc did not set temperature.");
+        return 8;
+    }
+
+    if (fabsf(exp->pressure - 8.0f) > FLT_EPSILON) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psExposureAlloc did not set pressure.");
+        return 9;
+    }
+
+    if (fabsf(exp->humidity - 9.0f) > FLT_EPSILON) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psExposureAlloc did not set humidity.");
+        return 10;
+    }
+
+    if (fabsf(exp->exposureTime - 10.0f) > FLT_EPSILON) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psExposureAlloc did not set exposureTime.");
+        return 11;
+    }
+
+    if (fabsf(exp->wavelength - 11.0f) > FLT_EPSILON) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psExposureAlloc did not set wavelength.");
+        return 12;
+    }
+
+    if (exp->observatory != obs) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psExposureAlloc did not set wavelength.");
+        return 12;
+    }
+
+    psFree(obs);
+    psFree(now);
+    psFree(exp);
+    return 0;
+}
+
+static int testObservatoryAlloc(void)
+{
+    char* name = "The Kaiser Royal Observatory";
+    psObservatory* obs = psObservatoryAlloc(name,
+                                            20.7*M_PI/180.0, 156.3*M_PI/180.0, 3055.0, 9.0);
+
+    if (fabs(obs->latitude - 20.7*M_PI/180.0) > DBL_EPSILON) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psObservatoryAlloc did not set latitude.");
+        return 1;
+    }
+
+    if (fabs(obs->longitude - 156.3*M_PI/180.0) > DBL_EPSILON) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psObservatoryAlloc did not set longitude.");
+        return 2;
+    }
+
+    if (fabs(obs->height - 3055.0) > DBL_EPSILON) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psObservatoryAlloc did not set height.");
+        return 3;
+    }
+
+    if (fabs(obs->tlr - 9.0) > DBL_EPSILON) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psObservatoryAlloc did not set tlr.");
+        return 4;
+    }
+
+    if (strcmp(obs->name,name) != 0) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psObservatoryAlloc did not set name.");
+        return 5;
+    }
+
+    if (obs->name == name) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psObservatoryAlloc did not copy name.");
+        return 6;
+    }
+
+    psObservatory* obs2 = psObservatoryAlloc(NULL,
+                          20.7*M_PI/180.0, 156.3*M_PI/180.0, 3055.0, 9.0);
+
+    if (obs2->name != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psObservatoryAlloc did not handle NULL name.");
+        return 7;
+    }
+
+    psFree(obs);
+    psFree(obs2);
+
+    return 0;
+}
+
+static int testFPAAlloc(void)
+{
+
+    psTime* now = psTimeGetTime(PS_TIME_UTC);
+    char* name = "The Kaiser Royal Observatory";
+
+    psObservatory* obs = psObservatoryAlloc(name,
+                                            20.7*M_PI/180.0, 156.3*M_PI/180.0, 3055.0, 0.0065f);
+
+    psExposure* exp = psExposureAlloc(1.0, 2.0, 3.0, 4.0, 5.0,
+                                      now, 6.0f, 260.0f, 1013.0f, 0.7f, 10.0f, 0.650f, obs);
+
+    /*
+        1. Call psFPAAlloc with nChips > 0 and a non-NULL psExposure.
+        a) Verify that the psExposure reference is: 1. is set in struct as
+        exposure; 2. its reference count is incremented.
+        b) Verify that the chip attribute is of the size specified by the
+        parameter nChips and that the chips array elements are all NULL.
+        c) verify that all other references in the struct is NULL.
+    */
+
+    psFPA* fpa = psFPAAlloc(8, exp);
+
+    if (fpa == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc returned a NULL.");
+        return 1;
+    }
+
+    if (fpa->exposure != exp) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc did not set the exposure.");
+        return 2;
+    }
+
+    if (psMemGetRefCounter(exp) != 2) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc did not increment reference counter for exposure.");
+        return 3;
+    }
+
+    if (fpa->chips->n != 8) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc did not set the number of chips properly.");
+        return 4;
+    }
+
+    for (int lcv=0; lcv < 8; lcv++) {
+        if (fpa->chips->data[lcv] != NULL) {
+            psLogMsg(__func__,PS_LOG_ERROR,
+                     "psFPAAlloc did not set chip %d to NULL.", lcv);
+            return 5;
+        }
+    }
+
+    if (fpa->metadata != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc did not set metadata to NULL.");
+        return 6;
+    }
+
+    if (fpa->fromTangentPlane != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc did not set fromTangentPlane to NULL.");
+        return 7;
+    }
+
+    if (fpa->toTangentPlane != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc did not set toTangentPlane to NULL.");
+        return 8;
+    }
+
+    if (fpa->pattern != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc did not set pattern to NULL.");
+        return 9;
+    }
+
+    if (fpa->grommit == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc did not set grommit using given exposure.");
+        return 10;
+    }
+
+    if (fpa->colorPlus != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc did not set colorPlus to NULL.");
+        return 11;
+    }
+
+    if (fpa->colorMinus != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc did not set colorMinus to NULL.");
+        return 12;
+    }
+
+    if (fpa->projection != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc did not set projection to NULL.");
+        return 13;
+    }
+
+    /*
+        2. Call psFPAAlloc with nChips = 0. Verify that the chips array is 
+           zero in size and the program execution does not stop.
+    */
+
+    psFPA* fpa2 = psFPAAlloc(0,exp);
+
+    if (fpa2->chips->n != 0) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc did not set the number of chips properly.");
+        return 14;
+    }
+
+    /*
+        3. Call psFPAAlloc with a NULL psExposure. Verify that the program 
+           execution doe not stop and the exposure attribute is NULL.
+    */
+
+    psFPA* fpa3 = psFPAAlloc(4,NULL);
+    if (fpa3->exposure != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psFPAAlloc did not set the exposure to NULL given NULL parameter.");
+        return 15;
+    }
+
+    /*
+        4. Call psFPAAlloc and set all references in the struct to a memory 
+           buffer. Verify that psFree cleans up all the buffers referenced in 
+           the struct, i.e., there is no memory leaks generated.
+    */
+
+    for (int lcv=0; lcv < 8; lcv++) {
+        fpa->chips->data[lcv] = psAlloc(4);
+    }
+
+    fpa->metadata = psAlloc(4);
+    fpa->fromTangentPlane = psAlloc(4);
+    fpa->toTangentPlane = psAlloc(4);
+    fpa->pattern = psAlloc(4);
+    fpa->colorPlus  = psAlloc(4);
+    fpa->colorMinus  = psAlloc(4);
+    fpa->projection  = psAlloc(4);
+
+    psFree(fpa3);
+    psFree(fpa2);
+    psFree(fpa);
+    psFree(exp);
+    psFree(obs);
+    psFree(now);
+
+    return 0;
+}
+
+static int testChipAlloc(void)
+{
+    char* name = "The Kaiser Royal Observatory";
+
+    psTime* now = psTimeGetTime(PS_TIME_UTC);
+
+    psObservatory* obs = psObservatoryAlloc(name,
+                                            20.7*M_PI/180.0, 156.3*M_PI/180.0, 3055.0, 0.0065f);
+
+    psExposure* exp = psExposureAlloc(1.0, 2.0, 3.0, 4.0, 5.0,
+                                      now, 6.0f, 260.0f, 1013.0f, 0.7f, 10.0f, 0.650f, obs);
+
+    psFPA* fpa = psFPAAlloc(8, exp);
+
+    // N.B. psFPAAlloc made made a reference to any of these that it is
+    // referencing, so these don't necessary are actually freed here.  Just
+    // these references to the buffers are freed.
+    psFree(exp);
+    psFree(obs);
+    psFree(now);
+
+    /*
+        1. invoke psChipAlloc with nCells > 0 and parentFPA non-NULL. Verify 
+           that:
+        a. the cells array is of the size nCells and all elements are NULL.
+        b. parent attribute is set to parentFPA parameter and the ref. count 
+           was incremented.
+        c. all other attributes are initialized to NULL or 0.
+    */
+
+    psChip* chip = psChipAlloc(8, fpa);
+
+    if (chip == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psChipAlloc returned NULL.");
+        return 1;
+    }
+
+    if (chip->cells->n != 8) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psChipAlloc did not set the number of cells properly.");
+        return 2;
+    }
+
+    for (int lcv=0; lcv < 8; lcv++) {
+        if (chip->cells->data[lcv] != NULL) {
+            psLogMsg(__func__,PS_LOG_ERROR,
+                     "psChipAlloc did not set cell %d to NULL.", lcv);
+            return 3;
+        }
+        chip->cells->data[lcv] = psAlloc(4); // to check if these are freed.
+    }
+
+    if (chip->parent != fpa) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psChipAlloc did not set the parent properly.");
+        return 4;
+    }
+
+    if (psMemGetRefCounter(fpa) != 1) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psChipAlloc incremented reference counter for parent FPA.");
+        return 5;
+    }
+
+    if (chip->metadata != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psChipAlloc did not set metadata to NULL.");
+        return 6;
+    }
+    chip->metadata = psAlloc(4); // to check if these are freed.
+
+    if (chip->toFPA != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psChipAlloc did not set toFPA to NULL.");
+        return 7;
+    }
+    chip->toFPA = psAlloc(4); // to check if these are freed.
+
+    if (chip->fromFPA != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psChipAlloc did not set fromFPA to NULL.");
+        return 8;
+    }
+    chip->fromFPA = psAlloc(4); // to check if these are freed.
+
+    /*
+        2. invoke psChipAlloc with nCells = 0. Verify that:
+        a. execution does not halt
+        b. the cells array is of the size of zero.    
+    */
+
+    psChip* chip2 = psChipAlloc(0,fpa);
+
+    if (chip2 == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psChipAlloc returned NULL.");
+        return 11;
+    }
+
+    if (chip2->cells->n != 0) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psChipAlloc did not set the number of cells properly.");
+        return 12;
+    }
+
+    if (chip2->parent != fpa) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psChipAlloc did not set the parent properly.");
+        return 14;
+    }
+
+    if (psMemGetRefCounter(fpa) != 1) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psChipAlloc incremented reference counter for parent FPA.");
+        return 15;
+    }
+
+    /*
+        3. invoke psChipAlloc with parentFPA = NULL. Verify that parent 
+           attribute is NULL and no error is generated.
+    */
+
+    psChip* chip3 = psChipAlloc(8,NULL);
+
+    if (chip3 == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psChipAlloc returned NULL.");
+        return 21;
+    }
+
+    if (chip3->cells->n != 8) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psChipAlloc did not set the number of cells properly.");
+        return 22;
+    }
+
+    if (chip3->parent != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psChipAlloc did not set the parent to NULL.");
+        return 24;
+    }
+
+    psFree(chip);
+    psFree(chip2);
+    psFree(chip3);
+    psFree(fpa);
+
+    return 0;
+}
+
+static int testCellAlloc(void)
+{
+    char* name = "The Kaiser Royal Observatory";
+
+    psTime* now = psTimeGetTime(PS_TIME_UTC);
+
+    psObservatory* obs = psObservatoryAlloc(name,
+                                            20.7*M_PI/180.0, 156.3*M_PI/180.0, 3055.0, 0.0065f);
+
+    psExposure* exp = psExposureAlloc(1.0, 2.0, 3.0, 4.0, 5.0,
+                                      now, 6.0f, 260.0f, 1013.0f, 0.7f, 10.0f, 0.650f, obs);
+
+    psFPA* fpa = psFPAAlloc(8, exp);
+
+    psChip* chip = psChipAlloc(8, fpa);
+
+    // N.B. psChipAlloc made a reference to any of these that it is
+    // referencing, so these are not actually freed here.  Just
+    // these references to the buffers are freed.
+    psFree(fpa);
+    psFree(exp);
+    psFree(obs);
+    psFree(now);
+
+    /*
+        1. invoke psCellAlloc with nReadouts > 0 and parentChip non-NULL. Verify that:
+        a. the readouts array is of the size nReadouts and all elements are NULL.
+        b. parent attribute is set to parentChip parameter and the ref. count 
+           was incremented.
+        c. all other attributes are initialized to NULL or 0.
+    */
+
+    psCell* cell1 = psCellAlloc(8,chip);
+
+    if (cell1 == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psCellAlloc returned NULL.");
+        return 1;
+    }
+
+    if (cell1->readouts->n != 8) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc did not set the number of readouts properly.");
+        return 2;
+    }
+
+    for (int lcv=0; lcv < 8; lcv++) {
+        if (cell1->readouts->data[lcv] != NULL) {
+            psLogMsg(__func__,PS_LOG_ERROR,
+                     "psCellAlloc did not set readout %d to NULL.", lcv);
+            return 3;
+        }
+        cell1->readouts->data[lcv] = psAlloc(4); // to check if these are freed.
+    }
+
+    if (cell1->parent != chip) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc did not set the parent properly.");
+        return 4;
+    }
+
+    if (psMemGetRefCounter(chip) != 1) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc incremented reference counter for parent.");
+        return 5;
+    }
+
+    if (cell1->metadata != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc did not set metadata to NULL.");
+        return 6;
+    }
+    cell1->metadata = psAlloc(4); // to check if these are freed.
+
+    if (cell1->toChip != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc did not set toChip to NULL.");
+        return 7;
+    }
+    cell1->toChip = psAlloc(4); // to check if these are freed.
+
+    if (cell1->fromChip != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc did not set fromChip to NULL.");
+        return 8;
+    }
+    cell1->fromChip = psAlloc(4); // to check if these are freed.
+
+    if (cell1->toFPA != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc did not set toFPA to NULL.");
+        return 9;
+    }
+    cell1->toFPA = psAlloc(4); // to check if these are freed.
+
+    if (cell1->toTP != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc did not set toTP to NULL.");
+        return 10;
+    }
+    cell1->toTP = psAlloc(4); // to check if these are freed.
+
+    /*
+        2. invoke psChipAlloc with nCells = 0. Verify that:
+        a. execution does not halt
+        b. the cells array is of the size of zero.    
+    */
+
+    psCell* cell2 = psCellAlloc(0,chip);
+
+    if (cell2 == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psCellAlloc returned NULL.");
+        return 11;
+    }
+
+    if (cell2->readouts->n != 0) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc did not set the number of readouts properly.");
+        return 12;
+    }
+
+    if (cell2->parent != chip) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc did not set the parent properly.");
+        return 14;
+    }
+
+    if (psMemGetRefCounter(chip) != 1) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc incremented reference counter for parent FPA.");
+        return 15;
+    }
+
+    /*
+        3. invoke psChipAlloc with parentFPA = NULL. Verify that parent 
+           attribute is NULL and no error is generated.
+    */
+
+    psCell* cell3 = psCellAlloc(8,NULL);
+
+    if (cell3 == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psCellAlloc returned NULL.");
+        return 21;
+    }
+
+    if (cell3->readouts->n != 8) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc did not set the number of cells properly.");
+        return 22;
+    }
+
+    if (cell3->parent != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psCellAlloc did not set the parent to NULL.");
+        return 24;
+    }
+
+    psFree(chip);
+    psFree(cell1);
+    psFree(cell2);
+    psFree(cell3);
+
+    return 0;
+}
+
+static int testReadoutAlloc(void)
+{
+    psImage* image = psImageAlloc(64,64,PS_TYPE_S8);
+
+
+    /*
+        1. invoke psReadoutAlloc with unique/non-zero x0,y0 and non-NULL image. Verify that:
+        a. col0 & row0 are set to the parameters x0 and y0, respectively.
+        b. image attribute is set to image parameter and referenece is incremented
+        c. mask, objects, and metadata attributes are all NULL
+    */
+    psReadout* readout = psReadoutAlloc(1,2,image);
+
+    if (readout == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psReadoutAlloc returned NULL.");
+        return 1;
+    }
+
+    if (readout->col0 != 1) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psReadoutAlloc did not set col0 properly.");
+        return 2;
+    }
+
+    if (readout->row0 != 2) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psReadoutAlloc did not set row0 properly.");
+        return 3;
+    }
+
+    if (readout->image != image) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psReadoutAlloc did not set the image properly.");
+        return 4;
+    }
+
+    if (psMemGetRefCounter(image) != 1) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psReadoutAlloc incremented reference counter for image.");
+        return 5;
+    }
+
+    if (readout->metadata != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psReadoutAlloc did not set metadata to NULL.");
+        return 6;
+    }
+    readout->metadata = psAlloc(4); // to check if these are freed.
+
+    if (readout->mask != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psReadoutAlloc did not set mask to NULL.");
+        return 7;
+    }
+    readout->mask = psAlloc(4); // to check if these are freed.
+
+    if (readout->objects != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psReadoutAlloc did not set objects to NULL.");
+        return 8;
+    }
+    readout->objects = psAlloc(4); // to check if these are freed.
+
+    /*
+        2. invoke psReadoutAlloc with NULL image. Verify that:
+        a. execution does not halt
+        b. the image attribute is NULL.
+    */
+
+    psReadout* readout2 = psReadoutAlloc(3,4,NULL);
+
+    if (readout2 == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psReadoutAlloc returned NULL.");
+        return 11;
+    }
+
+    if (readout2->image != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psReadoutAlloc didn't set image to NULL, as given.");
+        return 12;
+    }
+
+    psFree(readout);
+    psFree(readout2);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/astronomy/tst_psAstrometry01.c
===================================================================
--- /branches/rel3/psLib/test/astronomy/tst_psAstrometry01.c	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/tst_psAstrometry01.c	(revision 2163)
@@ -0,0 +1,521 @@
+/** @file  tst_psAstrometry01.c
+*
+*  @brief The code in this file will test the code in psAstrometry.[ch]
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-14 02:05:00 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include "psTest.h"
+#include "pslib.h"
+
+static int test1( void );
+static int test2( void );
+static int test3( void );
+
+testDescription tests[] = {
+                              {test1, 0000, "Tests psFixedPatternAlloc()", 0, false},
+                              {test2, 0000, "Tests psGrommitAlloc()", 0, false},
+                              {test3, 0000, "psFunctionBar", 0, false},
+                              {NULL}
+                          };
+#define RA  1.0
+#define DEC  2.0
+#define HA  3.0
+#define ZD  4.0
+#define AZ  5.0
+#define ROT_ANGLE 6.0
+#define TEMPERATURE 7.0
+#define PRESSURE 8.0
+#define HUMIDITY 20.0
+#define EXP_TIME 22.0
+#define WAVELENGTH 11.0
+#define NAME  "The Kaiser Royal Observatory"
+#define LATITUDE 20.7
+#define LONGITUDE 156.3
+#define HEIGHT  3055.0
+#define LAPSERATE 20.0
+
+#define NUM_READOUTS 2
+#define READOUT_NUM_ROWS 8
+#define READOUT_NUM_COLS 8
+
+#define CELL_WIDTH READOUT_NUM_COLS
+#define CELL_HEIGHT READOUT_NUM_ROWS
+
+#define CELL_GAP 2
+
+#define NUM_CELLS 4
+#define CELL_MIN_X 0
+#define CELL_MAX_X CELL_WIDTH
+#define CELL_MIN_Y 0
+#define CELL_MAX_Y CELL_HEIGHT
+
+#define NUM_CHIPS 2
+#define CHIP_MIN_X 0
+#define CHIP_MAX_X ((NUM_CELLS * CELL_WIDTH) + ((NUM_CELLS) * CELL_GAP))
+#define CHIP_MIN_Y 0
+#define CHIP_MAX_Y CELL_HEIGHT
+
+#define CHIP_WIDTH CHIP_MAX_X
+#define CHIP_HEIGHT CHIP_MAX_Y
+#define CHIP_GAP 2
+
+#define FPA_MIN_X 0
+#define FPA_MAX_X ((NUM_CHIPS * CHIP_WIDTH) + ((NUM_CHIPS) * CHIP_GAP))
+#define FPA_MIN_Y 0
+#define FPA_MAX_Y CHIP_HEIGHT
+
+#define ROW0  0
+#define COL0  0
+
+static void psPlaneDistortFree(psPlaneDistort *pd)
+{
+    psFree(pd->x);
+    psFree(pd->y);
+}
+
+static void psPlaneTransformFree(psPlaneTransform *pd)
+{
+    psFree(pd->x);
+    psFree(pd->y);
+}
+
+#define PS_CREATE_2D_IDENTITY_PLANE_TRANSFORM(NAME) \
+{\
+    NAME = (psPlaneTransform *) psAlloc(sizeof(psPlaneTransform)); \
+    p_psMemSetDeallocator(NAME, (psFreeFcn) psPlaneTransformFree); \
+    NAME->x = psDPolynomial2DAlloc(2, 2, PS_POLYNOMIAL_ORD); \
+    NAME->y = psDPolynomial2DAlloc(2, 2, PS_POLYNOMIAL_ORD); \
+    NAME->x->coeff[1][0] = 1.0; \
+    NAME->y->coeff[0][1] = 1.0; \
+}
+
+#define PS_CREATE_4D_IDENTITY_PLANE_DISTORT(NAME) \
+{\
+    NAME = (psPlaneDistort *) psAlloc(sizeof(psPlaneDistort)); \
+    p_psMemSetDeallocator(NAME, (psFreeFcn) psPlaneDistortFree); \
+    NAME->x = psDPolynomial4DAlloc(2, 2, 2, 2, PS_POLYNOMIAL_ORD); \
+    NAME->y = psDPolynomial4DAlloc(2, 2, 2, 2, PS_POLYNOMIAL_ORD); \
+    NAME->x->coeff[1][0][0][0] = 1.0; \
+    NAME->y->coeff[0][1][0][0] = 1.0; \
+}
+
+/*
+    This routine will create a system of FPAs/Chips/Cells/Readouts.  For
+    simplicity, an FPA is defined as a linear array of chips, and a chip is
+    defined as a linear array of cells, both in the x direction.  The transforms
+    between the various layers take into account the cell/chip and the boundaries
+    between each.
+*/
+psFPA *genSystem()
+{
+    int i;
+    int j;
+    int k;
+    psImage *tmpImage;
+    //    psTime* now = psTimeGetTime(PS_TIME_UTC);
+    //    psObservatory* obs = psObservatoryAlloc(NAME, LATITUDE, LONGITUDE, HEIGHT, LAPSERATE);
+    //    psExposure* exp = psExposureAlloc(RA, DEC, HA, ZD, AZ,
+    //                                      now, ROT_ANGLE, TEMPERATURE, PRESSURE, HUMIDITY,
+    //                                      EXP_TIME, WAVELENGTH, obs);
+    //    psGrommit *grom = psGrommitAlloc(exp);
+    psFPA *myFPA = psFPAAlloc(NUM_CHIPS, NULL);
+    psChip **chips;
+    psCell **cells;
+    psReadout **readouts;
+
+    // We create the transforms between the FPA and tangent plane.  The
+    // transform is a simple identity transform.
+    PS_CREATE_4D_IDENTITY_PLANE_DISTORT(myFPA->fromTangentPlane);
+    PS_CREATE_4D_IDENTITY_PLANE_DISTORT(myFPA->toTangentPlane);
+
+    chips = (psChip **) myFPA->chips->data;
+    for (i=0;i<NUM_CHIPS;i++) {
+        chips[i] = psChipAlloc(NUM_CELLS, myFPA);
+        // We create the transforms between the chip and FPA.  The
+        // transform is a simple identity transform.
+        PS_CREATE_2D_IDENTITY_PLANE_TRANSFORM(chips[i]->toFPA);
+        chips[i]->toFPA->x->coeff[0][0] = (double) (i * (CHIP_WIDTH + CHIP_GAP));
+        chips[i]->toFPA->x->coeff[1][1] = 0.0;
+        PS_CREATE_2D_IDENTITY_PLANE_TRANSFORM(chips[i]->fromFPA);
+        chips[i]->fromFPA->x->coeff[0][0] = (double) (-i * (CHIP_WIDTH + CHIP_GAP));
+        chips[i]->fromFPA->x->coeff[1][1] = 0.0;
+
+        cells = (psCell **) chips[i]->cells->data;
+
+        for (j=0;j<NUM_CELLS;j++) {
+            cells[j] = psCellAlloc(NUM_READOUTS, chips[i]);
+            // We create the transforms between the cell and the chip.  The
+            // transform is a simple identity transform.
+            PS_CREATE_2D_IDENTITY_PLANE_TRANSFORM(cells[j]->toChip);
+            cells[j]->toChip->x->coeff[0][0] = (double) (j * (CELL_WIDTH + CELL_GAP));
+            cells[j]->toChip->x->coeff[1][1] = 0.0;
+            PS_CREATE_2D_IDENTITY_PLANE_TRANSFORM(cells[j]->fromChip);
+            cells[j]->fromChip->x->coeff[0][0] = (double) (-j * (CELL_WIDTH + CELL_GAP));
+            cells[j]->fromChip->x->coeff[1][1] = 0.0;
+            PS_CREATE_2D_IDENTITY_PLANE_TRANSFORM(cells[j]->toFPA);
+            cells[j]->toFPA->x->coeff[0][0] = (double) ((i * (CHIP_WIDTH + CHIP_GAP)) +
+                                              (j * (CELL_WIDTH + CELL_GAP)));
+            cells[j]->toFPA->x->coeff[1][1] = 0.0;
+            PS_CREATE_2D_IDENTITY_PLANE_TRANSFORM(cells[j]->toTP);
+            cells[j]->toTP->x->coeff[0][0] = cells[j]->toFPA->x->coeff[0][0];
+            cells[j]->toTP->x->coeff[1][1] = 0.0;
+
+            readouts = (psReadout **) cells[j]->readouts->data;
+            for (k=0;k<NUM_READOUTS;k++) {
+                tmpImage = psImageAlloc(READOUT_NUM_COLS, READOUT_NUM_ROWS, PS_TYPE_F32);
+                for (int row=0;row<READOUT_NUM_ROWS;row++) {
+                    for(int col=0;col<READOUT_NUM_COLS;col++) {
+                        tmpImage->data.F32[row][col] = (float) ((i * (CHIP_WIDTH + CHIP_GAP)) +
+                                                                (j * (CELL_WIDTH + CELL_GAP)));
+                    }
+                }
+                readouts[k] = psReadoutAlloc((j * (CELL_WIDTH + CELL_GAP)), 0, tmpImage);
+
+            }
+        }
+    }
+
+    return(myFPA);
+}
+
+int main( int argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psImage", tests, argc, argv ) );
+}
+
+#define X_NUM_ROWS 4
+#define X_NUM_COLS 5
+#define Y_NUM_ROWS 6
+#define Y_NUM_COLS 7
+#define X_SCALE  1.0
+#define Y_SCALE  2.0
+#define X0  50.0
+#define Y0  60.0
+
+int test1( void )
+{
+    int i;
+    int j;
+    psFixedPattern *tmp = NULL;
+    float x0 = X0;
+    float y0 = Y0;
+    float xScale = X_SCALE;
+    float yScale = Y_SCALE;
+    psImage *x = psImageAlloc(X_NUM_COLS, X_NUM_ROWS, PS_TYPE_F64);
+    psImage *y = psImageAlloc(Y_NUM_COLS, Y_NUM_ROWS, PS_TYPE_F64);
+    int testStatus = 0;
+    int numPixels = 0;
+
+    for (i=0;i<X_NUM_ROWS;i++) {
+        for (j=0;j<X_NUM_COLS;j++) {
+            x->data.F64[i][j] = (double) (i + j);
+        }
+    }
+    for (i=0;i<Y_NUM_ROWS;i++) {
+        for (j=0;j<Y_NUM_COLS;j++) {
+            y->data.F64[i][j] = (double) (i - j);
+        }
+    }
+
+    tmp = psFixedPatternAlloc(x0, y0, xScale, yScale, x, y);
+
+    // Test the x pattern
+    for (i=0;i<X_NUM_ROWS;i++) {
+        for (j=0;j<X_NUM_COLS;j++) {
+            if ((tmp->x)[i][j] != x->data.F64[i][j]) {
+                printf("ERROR: (tmp->x)[%d][%d] is %f, should be %f\n", i, j,
+                       (tmp->x)[i][j], x->data.F64[i][j]);
+                testStatus = 1;
+                numPixels++;
+            }
+        }
+    }
+    if (numPixels != 0) {
+        printf("ERROR: x: %d incorrect pixels\n", numPixels);
+    }
+
+    // Test the y pattern
+    numPixels = 0;
+    for (i=0;i<Y_NUM_ROWS;i++) {
+        for (j=0;j<Y_NUM_COLS;j++) {
+            if ((tmp->y)[i][j] != y->data.F64[i][j]) {
+                printf("ERROR: (tmp->y)[%d][%d] is %f, should be %f\n", i, j,
+                       (tmp->y)[i][j], y->data.F64[i][j]);
+
+                testStatus = 1;
+                numPixels++;
+            }
+        }
+    }
+    if (numPixels != 0) {
+        printf("ERROR: y: %d incorrect pixels\n", numPixels);
+    }
+
+    // Test the x variables
+    if (tmp->nX != (X_NUM_ROWS * X_NUM_COLS)) {
+        printf("ERROR: tmp->nX is %d, should be %d\n", tmp->nX, (X_NUM_ROWS * X_NUM_COLS));
+        testStatus = 1;
+    }
+    if (tmp->x0 != X0) {
+        printf("ERROR: tmp->x0 is %f, should be %f\n", tmp->x0, X0);
+        testStatus = 1;
+    }
+    if (tmp->xScale != X_SCALE) {
+        printf("ERROR: tmp->xScale is %f, should be %f\n", tmp->xScale, X_SCALE);
+        testStatus = 1;
+    }
+
+    // Test the y variables
+    if (tmp->nY != (Y_NUM_ROWS * Y_NUM_COLS)) {
+        printf("ERROR: tmp->nY is %d, should be %d\n", tmp->nY, (Y_NUM_ROWS * Y_NUM_COLS));
+        testStatus = 1;
+    }
+    if (tmp->y0 != Y0) {
+        printf("ERROR: tmp->y0 is %f, should be %f\n", tmp->y0, Y0);
+        testStatus = 1;
+    }
+    if (tmp->yScale != Y_SCALE) {
+        printf("ERROR: tmp->yScale is %f, should be %f\n", tmp->yScale, Y_SCALE);
+        testStatus = 1;
+    }
+
+    psFree(tmp);
+    psFree(x);
+    psFree(y);
+
+    return 0;
+}
+
+int test2()
+{
+    int testStatus = 0;
+
+    psTime* now = psTimeGetTime(PS_TIME_UTC);
+
+    psObservatory* obs = psObservatoryAlloc(NAME, LATITUDE, LONGITUDE, HEIGHT, LAPSERATE);
+
+    psExposure* exp = psExposureAlloc(RA, DEC, HA, ZD, AZ,
+                                      now, ROT_ANGLE, TEMPERATURE, PRESSURE, HUMIDITY,
+                                      EXP_TIME, WAVELENGTH, obs);
+
+    psGrommit *grom = psGrommitAlloc(exp);
+
+    if (grom->height != HEIGHT) {
+        printf("ERROR: grom->height is %f, should be %f\n", grom->height, HEIGHT);
+        testStatus = 1;
+    }
+    if (grom->temperature != TEMPERATURE) {
+        printf("ERROR: grom->temperature is %f, should be %f\n", grom->temperature, TEMPERATURE);
+        testStatus = 2;
+    }
+
+    if (grom->pressure != PRESSURE) {
+        printf("ERROR: grom->pressure is %f, should be %f\n", grom->pressure, PRESSURE);
+        testStatus = 3;
+    }
+
+    if (grom->humidity != HUMIDITY) {
+        printf("ERROR: grom->humidity is %f, should be %f\n", grom->humidity, HUMIDITY);
+        testStatus = 4;
+    }
+
+    if (grom->wavelength != WAVELENGTH) {
+        printf("ERROR: grom->wavelength is %f, should be %f\n", grom->wavelength, WAVELENGTH);
+        testStatus = 5;
+    }
+
+    if (grom->lapseRate != LAPSERATE) {
+        printf("ERROR: grom->lapseRate is %f, should be %f\n", grom->lapseRate, LAPSERATE);
+        testStatus = 6;
+    }
+
+    /*
+        XXX: Don't know how to verify: latitude, sinLat, cosLat, abberationMag,
+             refractA, refractB, longitudeOffset, siderealTime
+     
+       if (grom-> != ) {
+            printf("ERROR: grom-> is %f, should be %f\n", grom->, );
+            testStatus = 1;
+       }
+    */
+
+    printf("grom->latitude is %f\n", grom->latitude);
+    printf("grom->sinLat is %f\n", grom->sinLat);
+    printf("grom->cosLat is %f\n", grom->cosLat);
+    printf("grom->abberationMag is %f\n", grom->abberationMag);
+    printf("grom->height is %f\n", grom->height);
+    printf("grom->temperature is %f\n", grom->temperature);
+    printf("grom->pressure is %f\n", grom->pressure);
+    printf("grom->humidity is %f\n", grom->humidity);
+    printf("grom->wavelength is %f\n", grom->wavelength);
+    printf("grom->lapseRate is %f\n", grom->lapseRate);
+    printf("grom->refractA is %f\n", grom->refractA);
+    printf("grom->refractB is %f\n", grom->refractB);
+    printf("grom->longitudeOffset is %f\n", grom->longitudeOffset);
+    printf("grom->siderealTime is %f\n", grom->siderealTime);
+
+    psFree(now);
+    psFree(obs);
+    psFree(exp);
+    psFree(grom);
+
+    return(testStatus);
+}
+
+int printCell(psCell *cell)
+{
+    psReadout **readouts = (psReadout **) cell->readouts->data;
+    psReadout *readout = readouts[0];
+
+    printf("-------------------------------\n");
+    for (int i = 0; i < readout->image->numRows ; i++) {
+        for (int j = 0; j < readout->image->numCols ; j++) {
+            printf("(%.1f) ", readout->image->data.F32[i][j]);
+        }
+        printf("\n");
+    }
+    return(0);
+}
+
+
+/******************************************************************************
+This routine tests many Astrometry functions:
+    psChipInFPA()
+    psCellInFPA()
+    psCoordFPAToChip()
+    psCoordChipToCell()
+This routine loops through all valid cell coordinates and maintains a running
+set of (x,y) coordinates in the FPA plane.  It calls the first two functions
+with each FPA coordinate and determines the chip/cell that that coordinate
+corresponds to.  It then calls the last two functions to determine the actual
+chip and cell coordinates.  The cell coordinate is verified for correctness.
+ 
+It then calls
+    psCoordCellToChip()
+to determine if the chip coordinates that were generated agree with the chip
+coords returned above.
+ 
+Then, it calls 
+    psCellInChip()
+and flags an ERROR if the cell it returns is different from that of
+psCellInFPA().
+ 
+Then, it calls
+    psCoordChipToFPA
+to determine if the FPA coordinates are correct.
+ 
+ 
+ *****************************************************************************/
+int test3( void )
+{
+    int x;
+    int y;
+    psPlane fpaCoord;
+    psFPA *myFPA = genSystem();
+    psCell *myCell = NULL;
+    psPlane chipCoord;
+    psPlane cellCoord;
+    psPlane testCoord;
+
+    int xReadout = 0;
+    int xFPA = 0;
+    for (int chip=0;chip<NUM_CHIPS;chip++) {
+        for (int cell=0;cell<NUM_CELLS;cell++) {
+            for(x=0;x<CELL_WIDTH;x++) {
+                for (y=0;y<CELL_HEIGHT;y++) {
+                    fpaCoord.x = (double) xFPA;
+                    fpaCoord.y = (double) y;
+                    //printf("------------------ (%f, %f) ------------------\n", fpaCoord.x, fpaCoord.y);
+                    psChip* tmpChip = psChipInFPA(&fpaCoord, myFPA);
+                    myCell = psCellInFPA(&fpaCoord, myFPA);
+
+                    if ((myCell == NULL) || (tmpChip == NULL)) {
+                        printf("ERROR: NULL\n");
+                    } else {
+                        psCoordFPAToChip(&chipCoord, &fpaCoord, tmpChip);
+                        psCoordChipToCell(&cellCoord, &chipCoord, myCell);
+
+                        if (x != (int) cellCoord.x) {
+                            printf("ERROR: x coord was %f, should be %d\n", cellCoord.x, x);
+                        }
+                        if (y != (int) cellCoord.y) {
+                            printf("ERROR: y coord was %f, should be %d\n", cellCoord.y, y);
+                        }
+
+                        psCoordCellToChip(&testCoord, &cellCoord, myCell);
+                        if (testCoord.x != chipCoord.x) {
+                            printf("ERROR: psCoordCellToChip() x coord was %f, should be %d\n", cellCoord.x, x);
+                        }
+                        if (testCoord.y != chipCoord.y) {
+                            printf("ERROR: psCoordCellToChip() y coord was %f, should be %d\n", cellCoord.y, y);
+                        }
+
+                        psCell *myCell2 = psCellInChip(&chipCoord, tmpChip);
+                        if (myCell2 != myCell) {
+                            printf("ERROR: psCellInFPA() != psCellInChip(psChipInFPA()) (%p %p)\n", myCell2, myCell);
+                            printCell(myCell2);
+                            printCell(myCell);
+
+                        }
+
+                        psCoordChipToFPA(&testCoord, &chipCoord, tmpChip);
+                        if (testCoord.x != xFPA) {
+                            printf("ERROR: psCoordChipToFPA() x coord was %f, should be %d\n", cellCoord.x, x);
+                        }
+                        if (testCoord.y != y) {
+                            printf("ERROR: psCoordChipToFPA() y coord was %f, should be %d\n", cellCoord.y, y);
+                        }
+
+                        psCoordFPAToTP(&testCoord, &fpaCoord, 0.0, 0.0, myFPA);
+                        if (testCoord.x != fpaCoord.x) {
+                            printf("ERROR: psCoordFPAToTP() x coord was %f, should be %d\n", cellCoord.x, x);
+                        }
+                        if (testCoord.y != fpaCoord.y) {
+                            printf("ERROR: psCoordFPAToTP() y coord was %f, should be %d\n", cellCoord.y, y);
+                        }
+
+                        psCoordCellToFPA(&testCoord, &cellCoord, myCell);
+                        if (testCoord.x != fpaCoord.x) {
+                            printf("ERROR: psCoordFPAToTP() x coord was %f, should be %d\n", cellCoord.x, x);
+                        }
+                        if (testCoord.y != fpaCoord.y) {
+                            printf("ERROR: psCoordFPAToTP() y coord was %f, should be %d\n", cellCoord.y, y);
+                        }
+
+                        psCoordTPToFPA(&testCoord, &fpaCoord, 0.0, 0.0, myFPA);
+                        if (testCoord.x != fpaCoord.x) {
+                            printf("ERROR: psCoordFPAToTP() x coord was %f, should be %d\n", cellCoord.x, x);
+                        }
+                        if (testCoord.y != fpaCoord.y) {
+                            printf("ERROR: psCoordFPAToTP() y coord was %f, should be %d\n", cellCoord.y, y);
+                        }
+                    }
+                }
+                xFPA++;
+                xReadout++;
+            }
+            // We skip the gaps between cells.
+            for(x=0;x<CELL_GAP;x++) {
+                xFPA++;
+                xReadout=0;
+            }
+        }
+        // We skip the gaps between chips.
+        for (x=0;x<CHIP_GAP;x++) {
+            xFPA++;
+            xReadout=0;
+        }
+    }
+
+    psFree(myFPA);
+    return(0);
+}
+//This code is
Index: /branches/rel3/psLib/test/astronomy/tst_psCoord.c
===================================================================
--- /branches/rel3/psLib/test/astronomy/tst_psCoord.c	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/tst_psCoord.c	(revision 2163)
@@ -0,0 +1,712 @@
+/** @file  tst_psImageManip.c
+*
+*  @brief The code will ...
+*
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-14 01:53:44 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include "psTest.h"
+#include "pslib.h"
+
+static int test1( void );
+static int test2( void );
+static int test3( void );
+static int test4( void );
+static int test5( void );
+static int test6( void );
+static int test7( void );
+static int test8( void );
+static int test20( void );
+static int test21( void );
+static int test40( void );
+static int test41( void );
+
+testDescription tests[] = {
+                              {test1, 0000, "psSphereTransformAlloc()", 0, false},
+                              {test2, 0000, "psPlaneTransformApply()", 0, false},
+                              {test3, 0000, "psPlaneDistortApply()", 0, false},
+                              {test4, 0000, "psPSphereTransformApply()", 0, false},
+                              {test5, 0000, "psSphereTransformICRStoEcliptic()", 0, false},
+                              {test6, 0000, "psSphereTransformEcliptictoICRS()", 0, false},
+                              {test7, 0000, "psSphereTransformICRStoGalatic()", 0, false},
+                              {test8, 0000, "psSphereTransformGalatictoICRS()", 0, false},
+                              {test20, 0000, "psProject()", 0, false},
+                              {test21, 0000, "psDeProject()", 0, false},
+                              {test40, 0000, "psSphereGetOffset()", 0, false},
+                              {test41, 0000, "psSphereSetOffset()", 0, false},
+                              {NULL}
+                          };
+
+#define ARCSEC_TO_RAD (M_PI / (180.0 * 60.0 * 60.0))
+#define ARCMIN_TO_RAD (M_PI / (180.0 * 60.0))
+#define DEG_TO_RAD (M_PI / 180.0)
+#define RAD_TO_DEG (180.0 / M_PI)
+#define RAD_TO_ARCMIN ((180.0 * 60.0) / M_PI)
+#define RAD_TO_ARCSEC ((180.0 * 60.0 * 60.0) / M_PI)
+
+
+int main( int argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psImage", tests, argc, argv ) );
+}
+
+#define MY_TINY 0.0001
+#define PS_COMPARE_TINY_THEN_PRINT_ERROR(ACTUAL, EXPECT, TESTSTATUS) \
+if (MY_TINY < fabs(EXPECT - ACTUAL)) { \
+    printf("ERROR: %s is %f, should be %f\n", #ACTUAL, ACTUAL, EXPECT); \
+    testStatus = TESTSTATUS; \
+}
+#define MY_TINY 0.0001
+#define PS_COMPARE_EPSILON_THEN_PRINT_ERROR(ACTUAL, EXPECT, TESTSTATUS) \
+if (MY_TINY < fabs(EXPECT - ACTUAL)) { \
+    printf("ERROR: %s is %f, should be %f\n", #ACTUAL, ACTUAL, EXPECT); \
+    testStatus = TESTSTATUS; \
+}
+
+#define PS_COT(X) (1.0 / atan(X))
+float p_psArg(float x,
+              float y)
+{
+    if (y!= 0.0) {
+        return(atan(y/x));
+    } else {
+        return(0.5 * M_PI);
+    }
+    return (0.0);
+}
+
+#define NPLAT 1.0
+#define X0_BIG 2.0
+#define X0_SMALL 2.0
+
+int test1( void )
+{
+    float tmpF32;
+    int testStatus = 0;
+    psSphereTransform *myST = psSphereTransformAlloc(NPLAT, X0_BIG, X0_SMALL);
+
+    tmpF32 = sin(NPLAT);
+    if (FLT_EPSILON < fabs(tmpF32 - myST->sinPhi)) {
+        printf("ERROR: myST->sinPhi is %f, should be %f\n", myST->sinPhi, tmpF32);
+        testStatus = 1;
+    }
+    tmpF32 = cos(NPLAT);
+    if (FLT_EPSILON < fabs(tmpF32 - myST->cosPhi)) {
+        printf("ERROR: myST->cosPhi is %f, should be %f\n", myST->cosPhi, tmpF32);
+        testStatus = 2;
+    }
+
+    if (FLT_EPSILON < fabs(X0_BIG - myST->Xo)) {
+        printf("ERROR: myST->Xo is %f, should be %f\n", myST->Xo, X0_BIG);
+        testStatus = 3;
+    }
+
+    if (FLT_EPSILON < fabs(X0_SMALL - myST->xo)) {
+        printf("ERROR: myST->xo is %f, should be %f\n", myST->xo, X0_SMALL);
+        testStatus = 4;
+    }
+
+    psFree(myST);
+    return(testStatus);
+}
+
+#define N 10
+// We do a simple identity transformation on a few x,y pairs.
+int test2( void )
+{
+    int i;
+    int testStatus = 0;
+    psPlane in;
+    psPlane out;
+    psPlaneTransform pt;
+
+    pt.x = psDPolynomial2DAlloc(2, 2, PS_POLYNOMIAL_ORD);
+    pt.y = psDPolynomial2DAlloc(2, 2, PS_POLYNOMIAL_ORD);
+    pt.x->coeff[1][0] = 1.0;
+    pt.y->coeff[0][1] = 1.0;
+    for (i=0;i<N;i++) {
+        in.x = (float) i;
+        in.y = (float) (i + 5.0);
+        in.xErr = 0.0;
+        in.yErr = 0.0;
+        psPlaneTransformApply(&out, &pt, &in);
+
+        if (FLT_EPSILON < fabs(out.x - in.x)) {
+            printf("ERROR: out.x is %f, should be %f\n", out.x, in.x);
+            testStatus = 3;
+        }
+
+        if (FLT_EPSILON < fabs(out.y - in.y)) {
+            printf("ERROR: out.y is %f, should be %f\n", out.y, in.y);
+            testStatus = 4;
+        }
+        //printf("psPlaneTransformApply(): (%f, %f) -> (%f, %f)\n", in.x, in.y, out.x, out.y);
+    }
+
+    psFree(pt.x);
+    psFree(pt.y);
+    return(testStatus);
+}
+
+#define COLOR 1.0
+#define MAGNITUDE 1.0
+// We do a simple identity transformation on a few x,y pairs.  For x and y,
+// we add in the COLOR and MAGNITUDE.
+int test3( void )
+{
+    int i;
+    int testStatus = 0;
+    psPlane in;
+    psPlane out;
+    psPlaneDistort pt;
+
+    pt.x = psDPolynomial4DAlloc(2, 2, 2, 2, PS_POLYNOMIAL_ORD);
+    pt.y = psDPolynomial4DAlloc(2, 2, 2, 2, PS_POLYNOMIAL_ORD);
+    pt.x->coeff[1][0][0][0] = 1.0;
+    pt.x->coeff[0][0][1][0] = 1.0;
+    pt.x->coeff[0][0][0][1] = 1.0;
+    pt.y->coeff[0][1][0][0] = 1.0;
+    pt.y->coeff[0][0][1][0] = 1.0;
+    pt.y->coeff[0][0][0][1] = 1.0;
+    for (i=0;i<N;i++) {
+        in.x = (float) i;
+        in.y = (float) (i + 5.0);
+        in.xErr = 0.0;
+        in.yErr = 0.0;
+        psPlaneDistortApply(&out, &pt, &in, COLOR, MAGNITUDE);
+
+        if (FLT_EPSILON < fabs(out.x - COLOR - MAGNITUDE - in.x)) {
+            printf("ERROR: out.x is %f, should be %f\n", out.x, in.x + COLOR + MAGNITUDE);
+            testStatus = 3;
+        }
+
+        if (FLT_EPSILON < fabs(out.y - COLOR - MAGNITUDE - in.y)) {
+            printf("ERROR: out.y is %f, should be %f\n", out.y, in.y + COLOR + MAGNITUDE);
+            testStatus = 3;
+        }
+        //printf("psPlaneTransformApply(): (%f, %f) -> (%f, %f)\n", in.x, in.y, out.x, out.y);
+    }
+
+    psFree(pt.x);
+    psFree(pt.y);
+    return(testStatus);
+}
+
+#define DEG_INC 30.0
+// We do a simple identity transformation on a few RA, DEC pairs.
+int test4( void )
+{
+    int testStatus = 0;
+    psSphere in;
+    psSphere out;
+    psSphereTransform *myST = psSphereTransformAlloc(0.0, 0.0, 0.0);
+
+    in.r = 45.0 * DEG_TO_RAD;
+    in.d = 30.0 * DEG_TO_RAD;
+    in.rErr = 0.0;
+    in.dErr = 0.0;
+
+    for (float r=0.0;r<180.0;r+=DEG_INC) {
+        for (float d=0.0;d<90.0;d+=DEG_INC) {
+            in.r = r * DEG_TO_RAD;
+            in.d = d * DEG_TO_RAD;
+            in.rErr = 0.0;
+            in.dErr = 0.0;
+
+            psSphereTransformApply(&out, myST, &in);
+
+            if (FLT_EPSILON < fabs(out.r - in.r)) {
+                printf("ERROR: out.r is %f, should be %f\n", out.r, in.r);
+                testStatus = 4;
+            }
+
+            if (FLT_EPSILON < fabs(out.d - in.d)) {
+                printf("ERROR: out.d is %f, should be %f\n", out.d, in.d);
+                testStatus = 5;
+            }
+            // printf("psSphereTransformApply (%f, %f) -> (%f, %f)\n", out.r, out.d, in.r, in.d);
+        }
+    }
+
+    psFree(myST);
+    return(testStatus);
+}
+
+int test5( void )
+{
+    int testStatus = 0;
+    psTime* now = psTimeGetTime(PS_TIME_UTC);
+    struct tm *tm_time = psTimeToTM(now);
+
+    // XXX: This test code is simply a copy of the original source code.
+    double year = (double)(1900 + tm_time->tm_year);
+    double T = year / 100.0;
+    double phi = -23.452294 + 0.013013 * T + 0.000001639 * T * T - 0.000000503 * T * T * T;
+    psSphereTransform *myST = psSphereTransformICRStoEcliptic(*now);
+
+    if (FLT_EPSILON < fabs(sin(phi) - myST->sinPhi)) {
+        printf("ERROR: myST->sinPhi is %f, should be %f\n", myST->sinPhi, sin(phi));
+        testStatus = 1;
+    }
+
+    if (FLT_EPSILON < fabs(cos(phi) - myST->cosPhi)) {
+        printf("ERROR: myST->cosPhi is %f, should be %f\n", myST->cosPhi, cos(phi));
+        testStatus = 2;
+    }
+
+    if (FLT_EPSILON < fabs(0.0 - myST->Xo)) {
+        printf("ERROR: myST->Xo is %f, should be %f\n", myST->Xo, X0_BIG);
+        testStatus = 3;
+    }
+
+    if (FLT_EPSILON < fabs(0.0 - myST->xo)) {
+        printf("ERROR: myST->xo is %f, should be %f\n", myST->xo, X0_SMALL);
+        testStatus = 4;
+    }
+
+    psFree(myST);
+    psFree(tm_time);
+    psFree(now);
+    return(testStatus);
+}
+
+
+int test6( void )
+{
+    int testStatus = 0;
+    psTime* now = psTimeGetTime(PS_TIME_UTC);
+    struct tm *tm_time = psTimeToTM(now);
+
+    // XXX: This test code is simply a copy of the original source code.
+    double year = (double)(1900 + tm_time->tm_year);
+    double T = year / 100.0;
+    double phi = +23.452294 - 0.013013 * T - 0.000001639 * T * T + 0.000000503 * T * T * T;
+    psSphereTransform *myST = psSphereTransformEcliptictoICRS(*now);
+
+    if (FLT_EPSILON < fabs(sin(phi) - myST->sinPhi)) {
+        printf("ERROR: myST->sinPhi is %f, should be %f\n", myST->sinPhi, sin(phi));
+        testStatus = 1;
+    }
+
+    if (FLT_EPSILON < fabs(cos(phi) - myST->cosPhi)) {
+        printf("ERROR: myST->cosPhi is %f, should be %f\n", myST->cosPhi, cos(phi));
+        testStatus = 2;
+    }
+
+    if (FLT_EPSILON < fabs(0.0 - myST->Xo)) {
+        printf("ERROR: myST->Xo is %f, should be %f\n", myST->Xo, X0_BIG);
+        testStatus = 3;
+    }
+
+    if (FLT_EPSILON < fabs(0.0 - myST->xo)) {
+        printf("ERROR: myST->xo is %f, should be %f\n", myST->xo, X0_SMALL);
+        testStatus = 4;
+    }
+
+    psFree(myST);
+    psFree(tm_time);
+    psFree(now);
+    return(testStatus);
+}
+
+
+int test7( void )
+{
+    int testStatus = 0;
+    // XXX: This test code is simply a copy of the original source code.
+    double phi = 62.6;
+    double Xo = 282.25;
+    double xo = 33.0;
+    psSphereTransform *myST = psSphereTransformICRStoGalatic();
+
+    if (FLT_EPSILON < fabs(sin(phi) - myST->sinPhi)) {
+        printf("ERROR: myST->sinPhi is %f, should be %f\n", myST->sinPhi, sin(phi));
+        testStatus = 1;
+    }
+
+    if (FLT_EPSILON < fabs(cos(phi) - myST->cosPhi)) {
+        printf("ERROR: myST->cosPhi is %f, should be %f\n", myST->cosPhi, cos(phi));
+        testStatus = 2;
+    }
+
+    if (FLT_EPSILON < fabs(Xo - myST->Xo)) {
+        printf("ERROR: myST->Xo is %f, should be %f\n", myST->Xo, Xo);
+        testStatus = 3;
+    }
+
+    if (FLT_EPSILON < fabs(xo - myST->xo)) {
+        printf("ERROR: myST->xo is %f, should be %f\n", myST->xo, xo);
+        testStatus = 4;
+    }
+
+    psFree(myST);
+    return(testStatus);
+}
+
+int test8( void )
+{
+    int testStatus = 0;
+    // XXX: This test code is simply a copy of the original source code.
+    double phi = -62.6;
+    double Xo = 33.0;
+    double xo = 282.25;
+    psSphereTransform *myST = psSphereTransformGalatictoICRS();
+
+    if (FLT_EPSILON < fabs(sin(phi) - myST->sinPhi)) {
+        printf("ERROR: myST->sinPhi is %f, should be %f\n", myST->sinPhi, sin(phi));
+        testStatus = 1;
+    }
+
+    if (FLT_EPSILON < fabs(cos(phi) - myST->cosPhi)) {
+        printf("ERROR: myST->cosPhi is %f, should be %f\n", myST->cosPhi, cos(phi));
+        testStatus = 2;
+    }
+
+    if (FLT_EPSILON < fabs(Xo - myST->Xo)) {
+        printf("ERROR: myST->Xo is %f, should be %f\n", myST->Xo, Xo);
+        testStatus = 3;
+    }
+
+    if (FLT_EPSILON < fabs(xo - myST->xo)) {
+        printf("ERROR: myST->xo is %f, should be %f\n", myST->xo, xo);
+        testStatus = 4;
+    }
+
+    psFree(myST);
+    return(testStatus);
+}
+
+int test20( void )
+{
+    int testStatus = 0;
+    psSphere in;
+    double R;
+    double expectX;
+    double expectY;
+    psPlane *out;
+    psProjection myProjection;
+    myProjection.R = 20.0 * DEG_TO_RAD;
+    myProjection.D = 10.0 * DEG_TO_RAD;
+    myProjection.Xs = 1.0;
+    myProjection.Ys = 1.0;
+
+    for (float r=0.0;r<180.0;r+=DEG_INC) {
+        for (float d=0.0;d<90.0;d+=DEG_INC) {
+            in.r = r * DEG_TO_RAD;
+            in.d = d * DEG_TO_RAD;
+            in.rErr = 0.0;
+            in.dErr = 0.0;
+
+            /******************************************************************
+             Tangent Plane Projection
+             *****************************************************************/
+            myProjection.type = PS_PROJ_TAN;
+            out = psProject(&in, &myProjection);
+
+            R = PS_COT(in.r) * (180.0 / M_PI);
+            expectX = R * sin(in.d);
+            expectY = R * cos(in.d);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->x, expectX, 1);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->y, expectY, 2);
+            psFree(out);
+
+            /******************************************************************
+             PS_PROJ_SIN Projection
+             *****************************************************************/
+            myProjection.type = PS_PROJ_SIN;
+            out = psProject(&in, &myProjection);
+
+            R = cos(in.r) * (180.0 / M_PI);
+            expectX = R * sin(in.d);
+            expectY = R * cos(in.d);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->x, expectX, 3);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->y, expectY, 4);
+            psFree(out);
+
+            /******************************************************************
+             PS_PROJ_CAR Projection
+             *****************************************************************/
+            myProjection.type = PS_PROJ_CAR;
+            out = psProject(&in, &myProjection);
+
+            expectX = in.d;
+            expectY = in.r;
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->x, expectX, 5);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->y, expectY, 6);
+            psFree(out);
+
+            /******************************************************************
+             PS_PROJ_MER Projection
+             *****************************************************************/
+            myProjection.type = PS_PROJ_MER;
+            out = psProject(&in, &myProjection);
+
+            expectX = in.d;
+            expectY = log(tan(45.0 + (0.5 * in.r))) * 180.0 / M_PI;
+
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->x, expectX, 7);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->y, expectY, 8);
+            psFree(out);
+
+            /******************************************************************
+             PS_PROJ_AIT Projection
+             *****************************************************************/
+            myProjection.type = PS_PROJ_AIT;
+            out = psProject(&in, &myProjection);
+
+            double alpha = 1.0 / ((180.0 / M_PI) * sqrt(1.0 + (cos(in.r) *
+                                  cos(0.5 * in.d) * 0.5)));
+            expectX = 2.0 * alpha * cos(in.r) * sin(0.5 * in.d);
+            expectY = alpha * sin(in.d);
+
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->x, expectX, 7);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->y, expectY, 8);
+            psFree(out);
+
+
+        }
+    }
+    return(testStatus);
+}
+
+#define SPACE_INC 10.0
+int test21( void )
+{
+    int testStatus = 0;
+    psPlane in;
+    double R;
+    double expectD;
+    double expectR;
+    psSphere *out;
+    psProjection myProjection;
+    myProjection.R = 20.0 * DEG_TO_RAD;
+    myProjection.D = 10.0 * DEG_TO_RAD;
+    myProjection.Xs = 1.0;
+    myProjection.Ys = 1.0;
+
+    in.xErr = 0.0;
+    in.yErr = 0.0;
+    for (in.x=0.0; in.x<100.0; in.x+=SPACE_INC) {
+        for (in.y=0.0;in.y<100.0;in.y+=SPACE_INC) {
+
+            /******************************************************************
+             Tangent Plane Projection
+             *****************************************************************/
+            myProjection.type = PS_PROJ_TAN;
+            out = psDeproject(&in, &myProjection);
+
+            R = sqrt((in.x * in.x) + (in.y * in.y));
+            expectD = p_psArg(-in.y, in.x);
+            expectR = atan(180.0 / (R * M_PI));
+
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->r, expectR, 1);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->d, expectD, 2);
+            psFree(out);
+
+            /******************************************************************
+             PS_PROJ_SIN Projection
+             *****************************************************************/
+            myProjection.type = PS_PROJ_SIN;
+            out = psDeproject(&in, &myProjection);
+
+            R = sqrt((in.x * in.x) + (in.y * in.y));
+            expectD = p_psArg(-in.y, in.x);
+            expectR = acos((R * M_PI) / 180.0);
+
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->r, expectR, 3);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->d, expectD, 4);
+            psFree(out);
+
+            /******************************************************************
+             PS_PROJ_CAR Projection
+             *****************************************************************/
+            myProjection.type = PS_PROJ_CAR;
+            out = psDeproject(&in, &myProjection);
+
+            expectD = in.x;
+            expectR = in.y;
+
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->r, expectR, 3);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->d, expectD, 4);
+            psFree(out);
+
+            /******************************************************************
+             PS_PROJ_MER Projection
+             *****************************************************************/
+            myProjection.type = PS_PROJ_MER;
+            out = psDeproject(&in, &myProjection);
+
+            expectD = in.x;
+            expectR = (2.0 * atan(exp((in.y * M_PI / 180.0)))) - 180.0;
+
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->r, expectR, 3);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->d, expectD, 4);
+            psFree(out);
+
+
+            /******************************************************************
+             PS_PROJ_AIT Projection
+             *****************************************************************/
+            myProjection.type = PS_PROJ_AIT;
+            out = psDeproject(&in, &myProjection);
+
+            float chu1 = (in.x * M_PI) / 720.0;
+            chu1 *= chu1;
+            float chu2 = (in.y * M_PI) / 360.0;
+            chu2 *= chu2;
+            float chu = sqrt(1.0 - chu1 - chu2);
+            expectD = 2.0 * p_psArg((2.0 * chu * chu) - 1.0, (in.x * chu * M_PI) / 360.0);
+            expectR = asin((in.y * chu * M_PI) / 180.0);
+
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->r, expectR, 3);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(out->d, expectD, 4);
+            psFree(out);
+        }
+    }
+    return(testStatus);
+}
+
+int test40( void )
+{
+    int testStatus = 0;
+    psSphere position1;
+    psSphere position2;
+    psSphere *offset = NULL;
+
+    position1.r = 90.0 * DEG_TO_RAD;
+    position1.d = 45.0 * DEG_TO_RAD;
+    position1.rErr = 0.0;
+    position1.dErr = 0.0;
+
+    for (float r=0.0;r<180.0;r+=DEG_INC) {
+        for (float d=0.0;d<90.0;d+=DEG_INC) {
+            position2.r = r * DEG_TO_RAD;
+            position2.d = d * DEG_TO_RAD;
+            position2.rErr = 0.0;
+            position2.dErr = 0.0;
+
+            offset = psSphereGetOffset(&position1, &position2,
+                                       PS_SPHERICAL, PS_RADIAN);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(offset->r, (position2.r - position1.r), 1);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(offset->d, (position2.d - position1.d), 1);
+            psFree(offset);
+
+            offset = psSphereGetOffset(&position1, &position2,
+                                       PS_SPHERICAL, PS_DEGREE);
+            offset->r = offset->r * DEG_TO_RAD;
+            offset->d = offset->d * DEG_TO_RAD;
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(offset->r, (position2.r - position1.r), 2);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(offset->d, (position2.d - position1.d), 3);
+            psFree(offset);
+
+            offset = psSphereGetOffset(&position1, &position2,
+                                       PS_SPHERICAL, PS_ARCMIN);
+            offset->r = offset->r * ARCMIN_TO_RAD;
+            offset->d = offset->d * ARCMIN_TO_RAD;
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(offset->r, (position2.r - position1.r), 2);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(offset->d, (position2.d - position1.d), 3);
+            psFree(offset);
+
+            offset = psSphereGetOffset(&position1, &position2,
+                                       PS_SPHERICAL, PS_ARCSEC);
+            offset->r = offset->r * ARCSEC_TO_RAD;
+            offset->d = offset->d * ARCSEC_TO_RAD;
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(offset->r, (position2.r - position1.r), 2);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(offset->d, (position2.d - position1.d), 3);
+            psFree(offset);
+
+            /* XXX: This code does not work correctly.
+                        offset = psSphereGetOffset(&position1, &position2,
+                                                   PS_LINEAR, 0);
+                        printf("--------------- (%f, %f) to (%f, %f) is (%f, %f) ---------------\n",
+                                position1.r, position1.d, position2.r, position2.d,
+                                offset->r, offset->d);
+                        PS_COMPARE_TINY_THEN_PRINT_ERROR(offset->r, (position2.r - position1.r), 1);
+                        PS_COMPARE_TINY_THEN_PRINT_ERROR(offset->d, (position2.d - position1.d), 1);
+                        psFree(offset);
+            */
+        }
+    }
+
+    return(testStatus);
+}
+
+int test41( void )
+{
+    int testStatus = 0;
+    psSphere position1;
+    psSphere *position2;
+    psSphere offset;
+    psSphere tmpOffset;
+
+    position1.r = 90.0 * DEG_TO_RAD;
+    position1.d = 45.0 * DEG_TO_RAD;
+    position1.rErr = 0.0;
+    position1.dErr = 0.0;
+
+    for (float r=0.0;r<180.0;r+=DEG_INC) {
+        for (float d=0.0;d<90.0;d+=DEG_INC) {
+            offset.r = r * DEG_TO_RAD;
+            offset.d = d * DEG_TO_RAD;
+            offset.rErr = 0.0;
+            offset.dErr = 0.0;
+
+            position2 = psSphereSetOffset(&position1, &offset,
+                                          PS_SPHERICAL, PS_RADIAN);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(position2->r, (position1.r + offset.r), 1);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(position2->d, (position1.d + offset.d), 1);
+            psFree(position2);
+
+            tmpOffset.r = offset.r * RAD_TO_DEG;
+            tmpOffset.d = offset.d * RAD_TO_DEG;
+            tmpOffset.rErr = 0.0;
+            tmpOffset.dErr = 0.0;
+            position2 = psSphereSetOffset(&position1, &tmpOffset,
+                                          PS_SPHERICAL, PS_DEGREE);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(position2->r, (position1.r + offset.r), 1);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(position2->d, (position1.d + offset.d), 1);
+            psFree(position2);
+
+            tmpOffset.r = offset.r * RAD_TO_ARCMIN;
+            tmpOffset.d = offset.d * RAD_TO_ARCMIN;
+            tmpOffset.rErr = 0.0;
+            tmpOffset.dErr = 0.0;
+            position2 = psSphereSetOffset(&position1, &tmpOffset,
+                                          PS_SPHERICAL, PS_ARCMIN);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(position2->r, (position1.r + offset.r), 1);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(position2->d, (position1.d + offset.d), 1);
+            psFree(position2);
+
+            tmpOffset.r = offset.r * RAD_TO_ARCSEC;
+            tmpOffset.d = offset.d * RAD_TO_ARCSEC;
+            tmpOffset.rErr = 0.0;
+            tmpOffset.dErr = 0.0;
+            position2 = psSphereSetOffset(&position1, &tmpOffset,
+                                          PS_SPHERICAL, PS_ARCSEC);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(position2->r, (position1.r + offset.r), 1);
+            PS_COMPARE_TINY_THEN_PRINT_ERROR(position2->d, (position1.d + offset.d), 1);
+            psFree(position2);
+
+            /* XXX: This code does not work correctly.
+                        position2 = psSphereSetOffset(&position1, &offset,
+                                                       PS_LINEAR, 0);
+                        printf("--------------- (%f, %f) and (%f, %f) is (%f, %f) ---------------\n",
+                                position1.r, position1.d, offset.r, offset.d, 
+                                position2->r, position2->d);
+                        PS_COMPARE_TINY_THEN_PRINT_ERROR(position2->r, (position1.r + offset.r), 1);
+                        PS_COMPARE_TINY_THEN_PRINT_ERROR(position2->d, (position1.d + offset.d), 1);
+                        psFree(position2);
+            */
+        }
+    }
+
+    return(testStatus);
+}
Index: /branches/rel3/psLib/test/astronomy/tst_psMetadataIO.c
===================================================================
--- /branches/rel3/psLib/test/astronomy/tst_psMetadataIO.c	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/tst_psMetadataIO.c	(revision 2163)
@@ -0,0 +1,186 @@
+/** @file  tst_psMetadataIO.c
+*
+*  @brief Test driver for psMetadataIO functions
+*
+*  This test driver contains the following tests for psMetadata:
+*    Test A - Read config file with overwrite set true
+*    Test B - Read config file with overwrite set false
+*    Test C - Read config file without auto-allocation of metadata
+*    Test D - Attempt to use null fileName argument
+*    Test E - Attempt to open nonexistant file
+*    Test F - Free psMetadata
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.2 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-10-06 22:51:31 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *metadataItem, char *spaces);
+
+static void printMetadataItemList(psList *metadataItemList)
+{
+    psMetadataItem *entryChild = NULL;
+
+    psListSetIterator(metadataItemList, PS_LIST_HEAD);
+    entryChild = psListGetCurrent(metadataItemList);
+    while (entryChild != NULL) {
+        printMetadataItem(entryChild, "    ");
+        entryChild = psListGetNext(metadataItemList);
+    }
+}
+
+static void printMetadataList(psList *metadataItemList)
+{
+    psMetadataItem *entryChild = NULL;
+
+    psListSetIterator(metadataItemList, PS_LIST_HEAD);
+    entryChild = psListGetCurrent(metadataItemList);
+    while (entryChild != NULL) {
+        printMetadataItem(entryChild, " ");
+        entryChild = psListGetNext(metadataItemList);
+    }
+}
+static void printMetadataItem(psMetadataItem *metadataItem, char *spaces)
+{
+
+    psVector *vec = NULL;
+
+
+    printf("%sKey Name: %8s  ", spaces, metadataItem->name);
+    printf("Key Type: %2d  ", metadataItem->type);
+
+    switch (metadataItem->type ) {
+    case PS_META_ITEM_SET:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_BOOL:
+        printf("Key Value: %15d  ", metadataItem->data.B);
+        break;
+    case PS_META_S32:
+        printf("Key Value: %15d  ", metadataItem->data.S32);
+        break;
+    case PS_META_F32:
+        printf("Key Value: %15.3f  ", metadataItem->data.F32);
+        break;
+    case PS_META_F64:
+        printf("Key Value: %15.3f  ", metadataItem->data.F64);
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    case PS_META_VEC:
+        vec = (psVector*)metadataItem->data.V;
+        printf("Key Value: ");
+        for(int i=0; i<vec->nalloc;i++) {
+            printf("%d ", vec->data.S32[i]);
+        }
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        printf("Value: unknown ");
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+
+    if(metadataItem->items->size) {
+        printMetadataItemList(metadataItem->items);
+    }
+}
+
+static void printMetadataTable(psHash *mdTable)
+{
+    int i;
+    psHashBucket* ptr = NULL;
+    for(i=0; i<mdTable->nbucket; i++) {
+        ptr = mdTable->buckets[i];
+        while (ptr != NULL) {
+            printMetadataItem(ptr->data, " ");
+            ptr = ptr->next;
+        }
+    }
+}
+
+static void printMetadata(psMetadata *metadata)
+{
+    printf("\nContents of metadata list:\n");
+    printMetadataList(metadata->list);
+    printf("\nContents of metadata table:\n");
+    printMetadataTable(metadata->table);
+}
+
+
+int main(int argc, char* argv[])
+{
+    // Test A - Read config file with overwrite set true
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Read config file with overwrite set true");
+    psMetadata *metadata1 = NULL;
+    int failedLines1 = 0;
+    failedLines1 = psMetadataParseConfig(&metadata1, "test.config", true);
+    printf("Failed lines: %d Expected: 6\n", failedLines1);
+    printMetadata(metadata1);
+    printFooter(stdout, "psMetadata", "Test A - Read config file with overwrite set true", true);
+
+
+    // Test B - Read config file with overwrite set false
+    printPositiveTestHeader(stdout, "psMetadata", "Test B - Read config file with overwrite set false");
+    psMetadata *metadata2 = NULL;
+    int failedLines2 = 0;
+    failedLines2 = psMetadataParseConfig(&metadata2, "test.config", false);
+    printf("Failed lines: %d Expected: 7", failedLines2);
+    printMetadata(metadata2);
+    printFooter(stdout, "psMetadata", "Test B - Read config file with overwrite set false", true);
+
+
+    // Test C - Read config file without auto-allocation of metadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test C - Read config file without auto-allocation of metadata");
+    psMetadata *metadata3 = psMetadataAlloc();
+    int failedLines3 = 0;
+    failedLines3 = psMetadataParseConfig(&metadata3, "test.config", false);
+    printf("Failed lines: %d Expected: 7", failedLines3);
+    printMetadata(metadata3);
+    printFooter(stdout, "psMetadata", "Test C - Read config file without auto-allocation of metadata", true);
+
+
+    // Test D - Attempt to use null fileName argument
+    printNegativeTestHeader(stdout,"psMetadataIO", "Test D - Attempt to use null fileName argument",
+                            "Null failedLines not allowed", 0);
+    psMetadataParseConfig(&metadata1, NULL, true);
+    printFooter(stdout, "psMetadata", "Test D - Attempt to use null fileName argument", true);
+
+
+    // Test E - Attempt to open nonexistant file
+    printNegativeTestHeader(stdout,"psMetadataIO", "Test E - Attempt to open nonexistant file",
+                            "Error opening file", 0);
+    psMetadataParseConfig(&metadata1, "abcedfg", true);
+    printFooter(stdout, "psMetadata", "Test E - Attempt to open nonexistant file", true);
+
+
+    // Test F - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test F - Free psMetadata");
+    psFree(metadata1);
+    psFree(metadata2);
+    psFree(metadata3);
+    psMemCheckLeaks(0, NULL, stdout);
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test F - Free psMetadata", true);
+
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/astronomy/tst_psMetadata_01.c
===================================================================
--- /branches/rel3/psLib/test/astronomy/tst_psMetadata_01.c	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/tst_psMetadata_01.c	(revision 2163)
@@ -0,0 +1,271 @@
+/** @file  tst_psMetadata_01.c
+*
+*  @brief Test driver for psMetadata functions
+*
+*  This test driver contains the following tests for psMetadata:
+*     Test A - Read 1st hdr from simple FITS file
+*     Test B - Read 2nd hdr from complex FITS file
+*     Test C - Read named hdr from complex FITS file
+*     Test D - Remove items with same name from all metadata
+*     Test E - Attempt to use null file descriptor
+*     Test F - Attempt to open nonexistant file
+*     Test G - Attempt to use two null inputs
+*     Test H - Attempt to use bad extNum
+*     Test I - Attempt to use bad extNameTest
+*     Test J - Free psMetadataData
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.12 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-10-15 19:26:31 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *metadataItem, char *spaces);
+
+static void printMetadataItemList(psList *metadataItemList)
+{
+    psMetadataItem *entryChild = NULL;
+
+    psListSetIterator(metadataItemList, PS_LIST_HEAD);
+    entryChild = psListGetCurrent(metadataItemList);
+    while (entryChild != NULL) {
+        printMetadataItem(entryChild, "    ");
+        entryChild = psListGetNext(metadataItemList);
+    }
+}
+
+static void printMetadataList(psList *metadataItemList)
+{
+    psMetadataItem *entryChild = NULL;
+
+    psListSetIterator(metadataItemList, PS_LIST_HEAD);
+    entryChild = psListGetCurrent(metadataItemList);
+    while (entryChild != NULL) {
+        printMetadataItem(entryChild, " ");
+        entryChild = psListGetNext(metadataItemList);
+    }
+}
+static void printMetadataItem(psMetadataItem *metadataItem, char *spaces)
+{
+    printf("%sKey Name: %8s  ", spaces, metadataItem->name);
+    printf("Key Type: %2d  ", metadataItem->type);
+
+    switch (metadataItem->type ) {
+    case PS_META_ITEM_SET:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_BOOL:
+        printf("Key Value: %15d  ", metadataItem->data.B);
+        break;
+    case PS_META_S32:
+        printf("Key Value: %15d  ", metadataItem->data.S32);
+        break;
+    case PS_META_F32:
+        printf("Key Value: %15.3f  ", metadataItem->data.F32);
+        break;
+    case PS_META_F64:
+        printf("Key Value: %15.3f  ", metadataItem->data.F64);
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        printf("Value: unknown ");
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+
+    if(metadataItem->items->size) {
+        printMetadataItemList(metadataItem->items);
+    }
+}
+
+static void printMetadataTable(psHash *mdTable)
+{
+    int i;
+    psHashBucket* ptr = NULL;
+    for(i=0; i<mdTable->nbucket; i++) {
+        ptr = mdTable->buckets[i];
+        while (ptr != NULL) {
+            printMetadataItem(ptr->data, " ");
+            ptr = ptr->next;
+        }
+    }
+}
+
+static void printMetadata(psMetadata *metadata)
+{
+    printf("Contents of metadata list:\n");
+    printMetadataList(metadata->list);
+    printf("\nContents of metadata table:\n");
+    printMetadataTable(metadata->table);
+}
+
+
+int main(int argc, char* argv[])
+{
+    psMetadata *metadata1 = NULL;
+    psMetadata *metadata2 = NULL;
+    psMetadata *metadata3 = NULL;
+
+
+    // Test A - Read 1st hdr from simple FITS file
+
+    /* Header contents for header_1.fits:
+
+        SIMPLE  =                    T / file does conform to FITS standard
+        BITPIX  =                    8 / number of bits per data pixel
+        NAXIS   =                    0 / number of data axes
+        HISTORY File modified by user 'harman' with fv  on 2004-08-04T11:11:18
+        END
+    */
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Read 1st hdr from simple FITS file");
+    metadata1 = psMetadataReadHeader(metadata1, NULL, 1, "header_1.fits");
+    printMetadata(metadata1);
+    printFooter(stdout, "psMetadata", "Test A - Read 1st hdr from simple FITS file", true);
+
+
+    // Test B - Read 2nd hdr from complex FITS file
+
+    /* Header contents for header_2.fits:
+
+        SIMPLE  =                    T / file does conform to FITS standard
+        BITPIX  =                  -64 / number of bits per data pixel
+        NAXIS   =                    1 / number of data axes
+        NAXIS1  =                   64 / length of data axis 1
+        EXTEND  =                    T / FITS dataset may contain extensions
+        COMMENT   FITS (Flexible Image Transport System) format is defined in 'Astronomy
+        COMMENT   and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H
+        END
+        <DATA>
+
+        XTENSION= 'IMAGE   '           / IMAGE extension
+        BITPIX  =                  -64 / number of bits per data pixel
+        NAXIS   =                    1 / number of data axes
+        NAXIS1  =                   64 / length of data axis 1
+        PCOUNT  =                    0 / required keyword; must = 0
+        GCOUNT  =                    1 / required keyword; must = 1
+        BITPIX  =                  -64 / number of bits per data pixel
+        EXTNAME = 'MY_DATA_1'
+        HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:14:45
+        HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:15:29
+        HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:21:18
+        HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:21:46
+        END
+        <DATA>
+
+        XTENSION= 'IMAGE   '           / IMAGE extension
+        BITPIX  =                  -64 / number of bits per data pixel
+        NAXIS   =                    1 / number of data axes
+        NAXIS1  =                   64 / length of data axis 1
+        PCOUNT  =                    0 / required keyword; must = 0
+        GCOUNT  =                    1 / required keyword; must = 1
+        EXTNAME = 'MY_DATA_2'
+        HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:22:12
+        HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:22:52
+        END
+        <DATA>
+    */
+    printPositiveTestHeader(stdout, "psMetadata", "Test B - Read 2nd hdr from complex FITS file");
+    metadata2 = psMetadataReadHeader(metadata2, NULL, 2, "header_2.fits");
+    printMetadata(metadata2);
+    printFooter(stdout, "psMetadata", "Test B - Read 2nd hdr from complex FITS file", true);
+
+
+    // Test C - Read named hdr from complex FITS file
+    printPositiveTestHeader(stdout, "psMetadata", "Test C - Read named hdr from complex FITS file");
+    metadata3 = psMetadataReadHeader(metadata3, "MY_DATA_2", -1, "header_2.fits");
+    printMetadata(metadata3);
+    printFooter(stdout, "psMetadata", "Test C - Read named hdr from complex FITS file", true);
+
+
+    // Test D - Remove items with same name from all metadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test D - Remove items with same name from all metadata");
+    printf("Removed HISTORY from all metadata from prior test. Resulting metadata:\n\n");
+    psMetadataRemove(metadata3, 0, "HISTORY");
+    printMetadata(metadata3);
+    printFooter(stdout, "psMetadata", "Test D - Remove items with same name from all metadata", true);
+
+
+    // Test E - Attempt to use null file filename
+    printNegativeTestHeader(stdout,"psMetadata", "Test E - Attempt to use null filename",
+                            "Null fileName not allowed", 0);
+    psMetadataReadHeader(NULL, NULL, 1, NULL);
+    printFooter(stdout, "psMetadata", "Test E - Attempt to use null filename", true);
+
+
+    // Test F - Attempt to open nonexistant file
+    printNegativeTestHeader(stdout,"psMetadata", "Test F - Attempt to open nonexistant file",
+                            "FITS error while opening file: missing.dat...Couldn't close FITS file...", 0);
+    psMetadataReadHeader(NULL, NULL, 1, "missing.dat");
+    printFooter(stdout, "psMetadata", "Test F - Attempt to open nonexistant file", true);
+
+
+    // Test G - Attempt to use two null inputs
+    printNegativeTestHeader(stdout,"psMetadata", "Test G - Attempt to use two null inputs",
+                            "Null extName and extNum = 0 not allowed", 0);
+    psMetadataReadHeader(NULL, NULL, 0, "header_2.fits");
+    printFooter(stdout, "psMetadata", "Test G - Attempt to use two null inputs", true);
+
+
+    // Test H - Attempt to use bad extNum
+    printNegativeTestHeader(stdout,"psMetadata", "Test H - Attempt to use bad extNum",
+                            "FITS error while locating header 22: tried to move past end of file", 0);
+    metadata1 = psMetadataReadHeader(metadata1, NULL, 22, "header_2.fits");
+    if (metadata1 != NULL ) {
+        psError(__func__,"psMetadataReadHeader did not return null when invalid ext given.");
+        return 10;
+    }
+    printFooter(stdout, "psMetadata", "Test H - Attempt to use bad extNum", true);
+
+
+    // Test I - Attempt to use bad extName
+    printNegativeTestHeader(stdout,"psMetadata", "Test I - Attempt to use bad extName",
+                            "FITS error while locating header AARGH: illegal HDU number", 0);
+    metadata1 = psMetadataReadHeader(NULL, "AARGH", -1, "header_2.fits");
+    if (metadata1 != NULL ) {
+        psError(__func__,"psMetadataReadHeader did not return null invalid extname give.");
+        return 11;
+    }
+    printFooter(stdout, "psMetadata", "Test I - Attempt to use bad extName", true);
+
+
+    // Test I1 - Attempt to use a valid named extension with invalid extnum
+    printNegativeTestHeader(stdout, "psMetadata", "Test I1 - Read named hdr w/ invalid extnum",
+                            "If extName specified, extNum should be -1.", 0);
+    metadata1 = psMetadataReadHeader(NULL, "MY_DATA_2", 0, "header_2.fits");
+    if (metadata1 != NULL ) {
+        psError(__func__,"psMetadataReadHeader did not return null w/ valid extname, invalid extnum");
+        return 12;
+    }
+    printFooter(stdout, "psMetadata", "Test C - Read named hdr from complex FITS file", true);
+
+
+    // Test J - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test J - Free psMetadata");
+    psFree(metadata1);
+    psFree(metadata2);
+    psFree(metadata3);
+    psMemCheckLeaks(0, NULL, stdout);
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test J - Free psMetadata", true);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/astronomy/tst_psMetadata_02.c
===================================================================
--- /branches/rel3/psLib/test/astronomy/tst_psMetadata_02.c	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/tst_psMetadata_02.c	(revision 2163)
@@ -0,0 +1,145 @@
+/** @file  tst_psMetadata_02.c
+*
+*  @brief Test driver for psMetadata functions
+*
+*  This test driver contains the following tests for psMetadata:
+*     Test A - Allocate metadata items
+*     Test B - Attempt to create metadata item with null name
+*     Test C - Attempt to create metadata item with invalid type
+*     Test D - Allocate metadata
+*     Test E - Attempt to add metadata item to null metadata
+*     Test F - Attempt to add null metadata item to metadata
+*     Test G - Free psMetadata
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-10-07 22:31:31 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *item)
+{
+    printf("Key Name: %8s  ", item->name);
+    printf("Key Type: %2d  ", item->type);
+
+    switch (item->type ) {
+    case PS_META_BOOL:
+        printf("Key Value: %15d  ", item->data.B);
+        break;
+    case PS_META_S32:
+        printf("Key Value: %15d  ", item->data.S32);
+        break;
+    case PS_META_F32:
+        printf("Key Value: %15.3f  ", item->data.F32);
+        break;
+    case PS_META_F64:
+        printf("Key Value: %15.3f  ", item->data.F64);
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)item->data.V);
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        printf("Value: unknown ");
+        break;
+    default:
+        printf("Bad type: %d ", item->type);
+    }
+    printf("Key Comment: %s\n", item->comment);
+}
+
+
+int main( int argc, char* argv[] )
+{
+    psMetadataItem *item1 = NULL;
+    psMetadata *metadata = NULL;
+    psMetadataItem *item2 = NULL;
+    psMetadataItem *item3 = NULL;
+    psMetadataItem *item4 = NULL;
+    psMetadataItem *item5 = NULL;
+    psMetadataItem *badItem = NULL;
+
+
+    // Test A - Allocate metadata items
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Allocate metadata items");
+    item1 = psMetadataItemAlloc("myItem1", PS_META_BOOL, "I am a boolean", true);
+    item2 = psMetadataItemAlloc("myItem2", PS_META_S32, "I am a signed integer", 111);
+    item3 = psMetadataItemAlloc("myItem3", PS_META_F32, "I am a single precision floating point", 222.222);
+    item4 = psMetadataItemAlloc("myItem4", PS_META_F64, "I am a double precision floating point", 333.333);
+    item5 = psMetadataItemAlloc("myItem5", PS_META_STR, "I am a string", "HELLO WORLD");
+    printMetadataItem(item1);
+    printMetadataItem(item2);
+    printMetadataItem(item3);
+    printMetadataItem(item4);
+    printMetadataItem(item5);
+    printFooter(stdout, "psMetadata", "Test A - Allocate metadata items", true);
+
+
+    // Test B - Attempt to create metadata item with null name
+    printNegativeTestHeader(stdout,"psMetadata", "Test B - Attempt to create metadata item with null name",
+                            "Null value for name not allowed", 0);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should produce error for null name.");
+    badItem = psMetadataItemAlloc(NULL, PS_META_STR, "I am a string", "HELLO WORLD");
+    if (badItem != NULL) {
+        psError(__func__,"psMetadataItemAlloc did not return null with null name item.");
+        return 10;
+    }
+    printFooter(stdout, "psMetadata", "Test B - Attempt to create metadata item with null name", true);
+
+
+    // Test C - Attempt to create metadata item with invalid type
+    printNegativeTestHeader(stdout,"psMetadata", "Test C - Attempt to create metadata item with invalid type",
+                            "Invalid psMetadataType: 6", 0);
+    badItem = psMetadataItemAlloc("badItem", PS_META_IMG, "I am bad", "Bad comment");
+    printFooter(stdout, "psMetadata", "Test C - Attempt to create metadata item with invalid type", true);
+
+
+    // Test D - Allocate metadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test D - Allocate metadata");
+    metadata = psMetadataAlloc();
+    printFooter(stdout, "psMetadata", "Test D - Allocate metadata", true);
+
+
+    // Test E - Attempt add metadata item to null metadata
+    printNegativeTestHeader(stdout,"psMetadata", "Test E - Attempt to add metadata item to null metadata",
+                            "Null metadata collection not allowed", 0);
+    psMetadataAddItem(NULL, item1, PS_LIST_HEAD);
+    printFooter(stdout, "psMetadata", "Test E - Attempt to add metadata item to null metadata", true);
+
+
+    // Test F - Attempt add null metadata item to metadata
+    printNegativeTestHeader(stdout,"psMetadata", "Test F - Attempt to add null metadata item to metadata",
+                            "Null metadata item not allowed", 0);
+    psMetadataAddItem(metadata, NULL, PS_LIST_HEAD);
+    printFooter(stdout, "psMetadata", "Test F - Attempt to add null metadata item to metadata", true);
+
+
+    // Test G - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test G - Free psMetadata");
+    psFree(item1);
+    psFree(item2);
+    psFree(item3);
+    psFree(item4);
+    psFree(item5);
+    psFree(badItem);
+    psFree(metadata);
+    psMemCheckLeaks(0, NULL, stdout);
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test G - Free psMetadata", true);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/astronomy/tst_psMetadata_03.c
===================================================================
--- /branches/rel3/psLib/test/astronomy/tst_psMetadata_03.c	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/tst_psMetadata_03.c	(revision 2163)
@@ -0,0 +1,241 @@
+/** @file  tst_psMetadata_03.c
+*
+*  @brief Test driver for psMetadata functions
+*
+*  This test driver contains the following tests for psMetadata:
+*     Test A - Allocate metadata and items
+*     Test B - Remove items from metadata by name
+*     Test C - Remove items from metadata by index
+*     Test D - Attempt to use null metadata
+*     Test E - Attempt to remove non-existant metadata item by name
+*     Test F - Attempt to remove non-existant metadata item by index
+*     Test G - Free psMetadata
+ *
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.7 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-10-08 01:33:14 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *item)
+{
+    printf("Key Name: %8s  ", item->name);
+    printf("Key Type: %2d  ", item->type);
+
+    switch (item->type ) {
+    case PS_META_BOOL:
+        printf("Key Value: %15d  ", item->data.B);
+        break;
+    case PS_META_S32:
+        printf("Key Value: %15d  ", item->data.S32);
+        break;
+    case PS_META_F32:
+        printf("Key Value: %15.3f  ", item->data.F32);
+        break;
+    case PS_META_F64:
+        printf("Key Value: %15.3f  ", item->data.F64);
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)item->data.V);
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        printf("Value: unknown ");
+        break;
+    default:
+        printf("Bad type: %d ", item->type);
+    }
+    printf("Key Comment: %s\n", item->comment);
+}
+
+
+int main( int argc, char* argv[] )
+{
+    psMetadataItem *item1 = NULL;
+    psMetadataItem *item2 = NULL;
+    psMetadataItem *item3 = NULL;
+    psMetadataItem *item4 = NULL;
+    psMetadataItem *errItem = NULL;
+    psMetadata *metadata = NULL;
+    psMetadata *errMetadata = NULL;
+    psHash *mdTable = NULL;
+    psList *mdList = NULL;
+    char *errName = NULL;
+
+    // Test A - Allocate metadata and items
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Allocate metadata items");
+    metadata = psMetadataAlloc();
+    item1 = psMetadataItemAlloc("myItem1", PS_META_BOOL, "I am a boolean", true);
+    item2 = psMetadataItemAlloc("myItem2", PS_META_S32, "I am a integer", 55);
+    item3 = psMetadataItemAlloc("myItem3", PS_META_BOOL, "I am a boolean", false);
+    item4 = psMetadataItemAlloc("myItem4", PS_META_S32, "I am a integer", 66);
+    errItem = psMetadataItemAlloc("errItem", PS_META_S32, "I am a integer", 99);
+    printMetadataItem(item1);
+    printMetadataItem(item2);
+    printMetadataItem(item3);
+    printMetadataItem(item4);
+    printFooter(stdout, "psMetadata", "Test A - Allocate metadata items", true);
+
+
+    // Test B - Remove items from metadata by name
+    printPositiveTestHeader(stdout, "psMetadata", "Test B - Remove items from metadata by name");
+    if( ! psMetadataAddItem(metadata, item1, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem did not return true when adding by name.");
+        return 10;
+    }
+    if( ! psMetadataAdd(metadata,PS_LIST_HEAD,"myItem2",PS_META_S32,"I am S32 integer",77) ) {
+        psError(__func__,"psMetadataAddItem did not return true when adding by name.");
+        return 11;
+    }
+    if ( ! psMetadataRemove(metadata, 0, "myItem1" ) ) {
+        psError(__func__,"psMetadataRemove did not return true when removing by name.");
+        return 12;
+    }
+    if ( ! psMetadataRemove(metadata, 0, "myItem2" ) ) {
+        psError(__func__,"psMetadataRemove did not return true when removing by name.");
+        return 13;
+    }
+    printFooter(stdout, "psMetadata", "Test B - Remove items from metadata by name", true);
+
+
+    // Test C - Remove items from metadata by index
+    printPositiveTestHeader(stdout, "psMetadata", "Test C - Remove items from metadata by index");
+    if ( ! psMetadataAddItem(metadata, item3, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem did not return true when adding by index.");
+        return 14;
+    }
+    if ( ! psMetadataAdd(metadata,PS_LIST_HEAD,"myItem4",PS_META_S32,"I am S32 integer",88) ) {
+        psError(__func__,"psMetadataAddItem did not return true when adding by index.");
+        return 15;
+    }
+    if( ! psMetadataRemove(metadata, 0, NULL) ) {
+        psError(__func__,"psMetadataRemove did not return true when removing by index.");
+        return 16;
+    }
+    if ( ! psMetadataRemove(metadata, 0, NULL ) ) {
+        psError(__func__,"psMetadataRemove did not return true when removing by index.");
+        return 17;
+    }
+    printFooter(stdout, "psMetadata", "Test C - Remove items from metadata by index", true);
+
+
+    // Test D - Attempt to use null metadata
+    printNegativeTestHeader(stdout,"psMetadata", "Test D - Attempt to use null metadata",
+                            "Null metadata collection not allowed", 0);
+    if ( psMetadataRemove(NULL, 0, NULL) ) {
+        psError(__func__,"psMetadataRemove did not return false when removing from null metadata.");
+        return 18;
+    }
+    printFooter(stdout, "psMetadata", "Test D - Attempt to use null metadata", true);
+
+
+    // Test E - Attempt to remove non-existant metadata item by name
+    printNegativeTestHeader(stdout,"psMetadata", "Test E - Attempt to remove non-existant metadata item by name",
+                            "Couldn't find metadata item. Name: AARGH", 0);
+    if( psMetadataRemove(metadata, 0, "AARGH") ) {
+        psError(__func__,"psMetadataRemove did not return false when removing non-existant item.");
+        return 19;
+    }
+    printFooter(stdout, "psMetadata", "Test E - Attempt to remove non-existant metadata item by name", true);
+
+
+    // Test F - Attempt to remove non-existant metadata item by index
+    printNegativeTestHeader(stdout,"psMetadata", "Test E - Attempt to remove non-existant metadata item by index",
+                            "Couldn't find metadata item in list. Index: 22", 0);
+    if( psMetadataRemove(metadata, 22, NULL) ) {
+        psError(__func__,"psMetadataRemove did not return false when removing non-existant item.");
+        return 20;
+    }
+    printFooter(stdout, "psMetadata", "Test E - Attempt to remove non-existant metadata item by index", true);
+
+
+    // Test H - Attempt to add item to an invalid metadata structure
+    printNegativeTestHeader(stdout,"psMetadata","Test H - Attempt to add item to metadata w/o hash table",
+                            "Couldn't add item to invalid metadata structure.",0);
+    errMetadata = psMetadataAlloc();
+    mdTable = errMetadata->table;
+    errMetadata->table = NULL;
+    if ( psMetadataAddItem(errMetadata, item3, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem did not return false w/ invalid metadata struct w/o hash table.");
+        return 21;
+    }
+    if ( psMetadataRemove(errMetadata, PS_LIST_HEAD, "errItem") ) {
+        psError(__func__,"psMetadataRemove did not return false w/ invalid metadata struct w/o hash table.");
+        return 31;
+    }
+    errMetadata->table = mdTable;
+    printFooter(stdout,"psMetadata","Test H - Attempt to add item to invalid metadata w/o hash table", true);
+
+    // Test J - Attempt to add item to an invalid metadata structure
+    printNegativeTestHeader(stdout,"psMetadata","Test J - Attempt to add item to metadata w/o link list",
+                            "Couldn't add item to invalid metadata structure.",0);
+    mdList = errMetadata->list;
+    errMetadata->list = NULL;
+    if ( psMetadataAddItem(errMetadata, item3, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem did not return false w/ invalid metadata struct w/o link list.");
+        return 22;
+    }
+    if ( psMetadataRemove(errMetadata, PS_LIST_HEAD, "errItem") ) {
+        psError(__func__,"psMetadataRemove did not return false w/ invalid metadata struct w/o link list.");
+        return 32;
+    }
+    errMetadata->list = mdList;
+    printFooter(stdout,"psMetadata","Test J - Attempt to add item to invalid metadata w/o link list", true);
+
+    // Test K - Attempt to add item with a null name
+    printNegativeTestHeader(stdout,"psMetadata","Test K - Attempt to add item with null name",
+                            "Couldn't add item with null name.",0);
+    errName = errItem->name;
+    errItem->name = NULL;
+    if ( psMetadataAddItem(errMetadata, errItem, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem did not return false with item with null name.");
+        return 23;
+    }
+    errItem->name = errName;
+    printFooter(stdout,"psMetadata","Test K - Attempt to add item with null name", true);
+
+    // Test L - Attempt to add item to an invalid metadata structure
+    printNegativeTestHeader(stdout,"psMetadata","Test L - Attempt to add item to metadata w/o hash table",
+                            "Couldn't add item to invalid metadata structure.",0);
+    mdTable = errMetadata->table;
+    errMetadata->table = NULL;
+    if ( psMetadataAdd(errMetadata, PS_LIST_HEAD, "errItem", PS_META_S32,"Integer",22) ) {
+        psError(__func__,"psMetadataAddItem did not return false w/ invalid metadata struct w/o hash table.");
+        return 24;
+    }
+    errMetadata->table = mdTable;
+    printFooter(stdout,"psMetadata","Test L - Attempt to add item to invalid metadata w/o hash table", true);
+
+    // Test G - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test G - Free psMetadata");
+    psFree(metadata);
+    psFree(item1);
+    psFree(item2);
+    psFree(item3);
+    psFree(item4);
+    psFree(errItem);
+    psFree(errMetadata);
+    if( psMemCheckLeaks(0, NULL, stdout) != 0 ) {
+        psError(__func__,"Memory leaks detected.");
+        return 25;
+    }
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test G - Free psMetadata", true);
+
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/astronomy/tst_psMetadata_04.c
===================================================================
--- /branches/rel3/psLib/test/astronomy/tst_psMetadata_04.c	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/tst_psMetadata_04.c	(revision 2163)
@@ -0,0 +1,212 @@
+
+/** @file  tst_psMetadata_04.c
+*
+*  @brief Test driver for psMetadata functions
+*
+*  This test driver contains the following tests for psMetadata:
+*     Test A - Allocate metadata and items
+*     Test B - Lookup metadata item by name
+*     Test C - Attempt to use null metadata
+*     Test D - Attempt to use null key
+*     Test E - Attempt to lookup non-existant metadata item
+*     Test F - Lookup metadata item by index
+*     Test G - Attempt to use null metadata
+*     Test H - Attempt to get non-existant metadata item
+*     Test I - Free psMetadata
+*     Test J - Attempt to look up with an invalid metadata object
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-10-08 20:53:21 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *item)
+{
+    printf("Key Name: %8s  ", item->name);
+    printf("Key Type: %2d  ", item->type);
+
+    switch (item->type ) {
+    case PS_META_BOOL:
+        printf("Key Value: %15d  ", item->data.B);
+        break;
+    case PS_META_S32:
+        printf("Key Value: %15d  ", item->data.S32);
+        break;
+    case PS_META_F32:
+        printf("Key Value: %15.3f  ", item->data.F32);
+        break;
+    case PS_META_F64:
+        printf("Key Value: %15.3f  ", item->data.F64);
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)item->data.V);
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        printf("Value: unknown ");
+        break;
+    default:
+        printf("Bad type: %d ", item->type);
+    }
+    printf("Key Comment: %s\n", item->comment);
+}
+
+
+int main( int argc, char* argv[] )
+{
+    psMetadataItem *item1 = NULL;
+    psMetadataItem *item2 = NULL;
+    psMetadataItem *item3 = NULL;
+    psMetadataItem *item4 = NULL;
+    psMetadataItem *item = NULL;
+    psMetadata *metadata = NULL;
+    psHash* tmpTable = NULL;
+    psList* tmpList = NULL;
+
+    // Test A - Allocate metadata and items
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Allocate metadata items");
+    metadata = psMetadataAlloc();
+    item1 = psMetadataItemAlloc("myItem1", PS_META_BOOL, "I am a boolean", true);
+    item2 = psMetadataItemAlloc("myItem2", PS_META_S32, "I am a integer", 55);
+    item3 = psMetadataItemAlloc("myItem3", PS_META_BOOL, "I am a boolean", false);
+    item4 = psMetadataItemAlloc("myItem4", PS_META_S32, "I am a integer", 66);
+    printMetadataItem(item1);
+    printMetadataItem(item2);
+    printMetadataItem(item3);
+    printMetadataItem(item4);
+    psMetadataAddItem(metadata, item1, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item2, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item3, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item4, PS_LIST_HEAD);
+    printFooter(stdout, "psMetadata", "Test A - Allocate metadata items", true);
+
+
+    // Test B - Lookup metadata item by name
+    printPositiveTestHeader(stdout, "psMetadata", "Test B - Lookup metadata item by name");
+    item = psMetadataLookup(metadata, "myItem2");
+    printf("Found item named %s\n", item->name);
+    if(item == NULL) {
+        printf("ERROR: Item should not be null\n");
+        return 10;
+    }
+    printFooter(stdout, "psMetadata", "Test B - Lookup metadata item by name", true);
+
+
+    // Test C - Attempt to use null metadata
+    printNegativeTestHeader(stdout,"psMetadata", "Test C - Attempt to use null metadata",
+                            "Null metadata collection not allowed", 0);
+    if ( psMetadataLookup(NULL, "myItem2") != NULL ) {
+        psError(__func__,"psMetadataLookup did not return NULL with null metadata.");
+        return 11;
+    }
+    printFooter(stdout, "psMetadata", "Test C - Attempt to use null metadata", true);
+
+
+    // Test D - Attempt to use null key
+    printNegativeTestHeader(stdout,"psMetadata", "Test D - Attempt to use null key",
+                            "Null key name not allowed", 0);
+    if ( psMetadataLookup(metadata, NULL) != NULL ) {
+        psError(__func__,"psMetadata did not return NULL with null key.");
+        return 12;
+    }
+    printFooter(stdout, "psMetadata", "Test D - Attempt to use null key", true);
+
+
+    // Test E - Attempt to lookup non-existant metadata item
+    printNegativeTestHeader(stdout,"psMetadata", "Test E - Attempt to lookup non-existant metadata item",
+                            "Couldn't find metadata item. Name: AARGH", 0);
+    if ( psMetadataLookup(metadata, "AARGH") != NULL ) {
+        psError(__func__,"psMetadata did not return NULL with a non-existant item.");
+        return 13;
+    }
+    printFooter(stdout, "psMetadata", "Test E - Attempt to lookup non-existant metadata item", true);
+
+
+    // Test F - Lookup metadata item by index
+    printPositiveTestHeader(stdout, "psMetadata", "Test F - Lookup metadata item by index");
+    item = psMetadataGet(metadata, 0);
+    printf("Found item named %s\n", item->name);
+    if(item == NULL) {
+        printf("ERROR: Item should not be null\n");
+        return 14;
+    }
+    printFooter(stdout, "psMetadata", "Test F - Lookup metadata item by index", true);
+
+
+    // Test G - Attempt to use null metadata
+    printNegativeTestHeader(stdout,"psMetadata", "Test G - Attempt to use null metadata",
+                            "Null metadata collection not allowed", 0);
+    item = psMetadataGet(NULL, 0);
+    if ( item != NULL ) {
+        psError(__func__,"psMetadataGet did not return NULL with null metadata structure.");
+        return 15;
+    }
+    printFooter(stdout, "psMetadata", "Test G - Attempt to use null metadata", true);
+
+
+    // Test H - Attempt to get non-existant metadata item
+    printNegativeTestHeader(stdout,"psMetadata", "Test H - Attempt to get non-existant metadata item",
+                            "Couldn't find metadata item with given index. Index: 22", 0);
+    if ( psMetadataGet(metadata, 22) != NULL ) {
+        psError(__func__,"psMetadataGet did not return NULL with non-existant metadata item.");
+        return 16;
+    }
+    printFooter(stdout, "psMetadata", "Test H - Attempt to get non-existant metadata item", true);
+
+    // Test J - Attempt to look up with an invalid metadata object
+    printNegativeTestHeader(stdout,"psMetadata","Test J - Attemp to look up with an invalid metadata",
+                            "Lookup item with invalid metadata object.", 0 );
+    tmpTable = metadata->table;
+    metadata->table = NULL;
+    if ( psMetadataLookup(metadata,"myItem2") != NULL ) {
+        psError(__func__,"psMetadataLookup did not return null for invalid metadata object.");
+        return 20;
+    }
+    metadata->table = tmpTable;
+    printFooter(stdout, "psMetadata","Test J - Attempt to lookup an invalid metadata object.",true);
+
+    // Test K - Attempt get item  with an invalid metadata object
+    printNegativeTestHeader(stdout,"psMetadata","Test K - Attemp to get item with an invalid metadata",
+                            "Get item with invalid metadata object.", 0 );
+    tmpList = metadata->list;
+    metadata->list = NULL;
+    if ( psMetadataGet(metadata,0) != NULL ) {
+        psError(__func__,"psMetadataLookup did not return null for invalid metadata object.");
+        return 20;
+    }
+    metadata->list = tmpList;
+    printFooter(stdout, "psMetadata","Test K - Attempt to get item with  invalid metadata object.",true);
+
+    // Test I - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test I - Free psMetadata");
+    psFree(metadata);
+    psFree(item1);
+    psFree(item2);
+    psFree(item3);
+    psFree(item4);
+    if ( psMemCheckLeaks(0, NULL, stdout) != 0 ) {
+        psError(__func__,"memory leaks detected.");
+        return 20;
+    }
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+        return 21;
+    }
+    printFooter(stdout, "psMetadata", "Test I - Free psMetadata", true);
+
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/astronomy/tst_psMetadata_05.c
===================================================================
--- /branches/rel3/psLib/test/astronomy/tst_psMetadata_05.c	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/tst_psMetadata_05.c	(revision 2163)
@@ -0,0 +1,282 @@
+
+
+/** @file  tst_psMetadata_05.c
+*
+*  @brief Test driver for psMetadata functions
+*
+*  This test driver contains the following tests for psMetadata:
+*     Test A - Allocate metadata and items
+*     Test B - Set iterator at second index
+*     Test C - Get next item at index
+*     Test D - Get next item at index and string
+*     Test E - Get previous item at index
+*     Test F - Write metadata item to file
+*     Test G - Attempt to use null metadata with setIterator
+*     Test H - Attempt to use null metadata with getNext
+*     Test I - Attempt to use null metadata with getPrevious
+*     Test J - Attempt to use null file with itemPrint
+*     Test K - Attempt to use null format with itemPrint
+*     Test L - Attempt to use null item with itemPrint
+*     Test M - Free psMetadata
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.7 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-10-12 01:40:32 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *item)
+{
+    printf("Key Name: %8s  ", item->name);
+    printf("Key Type: %2d  ", item->type);
+
+    switch (item->type ) {
+    case PS_META_BOOL:
+        printf("Key Value: %15d  ", item->data.B);
+        break;
+    case PS_META_S32:
+        printf("Key Value: %15d  ", item->data.S32);
+        break;
+    case PS_META_F32:
+        printf("Key Value: %15.3f  ", item->data.F32);
+        break;
+    case PS_META_F64:
+        printf("Key Value: %15.3f  ", item->data.F64);
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)item->data.V);
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        printf("Value: unknown ");
+        break;
+    default:
+        printf("Bad type: %d ", item->type);
+    }
+    printf("Key Comment: %s\n", item->comment);
+}
+
+
+int main( int argc, char* argv[] )
+{
+    long data;
+    psF32 fpdata;
+    psMetadataItem *item1 = NULL;
+    psMetadataItem *item2 = NULL;
+    psMetadataItem *item3 = NULL;
+    psMetadataItem *item4 = NULL;
+    psMetadataItem *item5 = NULL;
+    psMetadataItem *item6 = NULL;
+    psMetadataItem *item7 = NULL;
+    psMetadataItem *item8 = NULL;
+    psMetadataItem *item = NULL;
+    psMetadata *metadata = NULL;
+    FILE *fd = NULL;
+    char str[7];
+    psList* tmpList = NULL;
+
+    // Test A - Allocate metadata and items
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Allocate metadata items");
+    metadata = psMetadataAlloc();
+    item1 = psMetadataItemAlloc("myItem1", PS_META_BOOL, "I am a boolean", true);
+    item2 = psMetadataItemAlloc("myItem2", PS_META_S32, "I am a integer", 55);
+    item3 = psMetadataItemAlloc("myItem3", PS_META_BOOL, "I am a boolean", false);
+    item4 = psMetadataItemAlloc("myItem4", PS_META_S32, "I am a integer", 66);
+    item5 = psMetadataItemAlloc("myItem5", PS_META_F32, "I am a float", 3.14);
+    item6 = psMetadataItemAlloc("myItem6", PS_META_F64, "I am a double", 6.28);
+    item7 = psMetadataItemAlloc("myItem7", PS_META_STR, "I am a string", "GNIRTS");
+    item8 = psMetadataItemAlloc("myItem8", PS_META_UNKNOWN, "I am unknown");
+    printMetadataItem(item1);
+    printMetadataItem(item2);
+    printMetadataItem(item3);
+    printMetadataItem(item4);
+    psMetadataAddItem(metadata, item1, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item2, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item3, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item4, PS_LIST_HEAD);
+    printFooter(stdout, "psMetadata", "Test A - Allocate metadata items", true);
+
+
+    // Test B - Set iterator at second index
+    printPositiveTestHeader(stdout, "psMetadata", "Test B - Set iterator at second index");
+    psMetadataSetIterator(metadata, 2);
+    printFooter(stdout, "psMetadata", "Test B - Set iterator at second index", true);
+
+
+    // Test C - Get next item at index
+    printPositiveTestHeader(stdout, "psMetadata", "Test C - Get next item at index");
+    item = psMetadataGetNext(metadata, NULL, 2);
+    if(item == NULL) {
+        printf("ERROR: Item should not be null\n");
+    } else {
+        printf("Found item named %s\n", item->name);
+    }
+    printFooter(stdout, "psMetadata", "Test C - Get next item at index", true);
+
+
+    // Test D - Get next item at index and string
+    printPositiveTestHeader(stdout, "psMetadata", "Test D - Get next item at index and string");
+    item = psMetadataGetNext(metadata, "myItem1", 1);
+    if(item == NULL) {
+        printf("ERROR: Item should not be null\n");
+    } else {
+        printf("Found item named %s\n", item->name);
+    }
+    printFooter(stdout, "psMetadata", "Test D - Get next item at index and string", true);
+
+
+    // Test E - Get previous item at index
+    printPositiveTestHeader(stdout, "psMetadata", "Test E - Get previous item at index");
+    item = psMetadataGetPrevious(metadata, NULL, 1);
+    if(item == NULL) {
+        printf("ERROR: Item should not be null\n");
+    } else {
+        printf("Found item named %s\n", item->name);
+    }
+    if( psMetadataGetPrevious(metadata,"myItem3",1) == NULL) {
+        psError(__func__,"psMetadataGetPrevious did not return an item from metadata.");
+        return 45;
+    }
+    tmpList = metadata->list;
+    metadata->list = NULL;
+    if ( psMetadataGetPrevious(metadata,NULL,1) != NULL) {
+        psError(__func__,"psMetadataGetPrevious did not return null for invalid metadata.");
+        return 50;
+    }
+    metadata->list = tmpList;
+    printFooter(stdout, "psMetadata", "Test E - Get previous item at index", true);
+
+
+    // Test F - Write metadata item to file
+    printPositiveTestHeader(stdout, "psMetadata", "Test F - Write metadata item to file");
+    fd = fopen("./tst_psMetadata05_OUT", "w");
+    if(fd == NULL) {
+        printf("ERROR: Couldn't open file for writing\n");
+    }
+    psMetadataItemPrint(fd, "S32  = %ld\n", item2);
+    psMetadataItemPrint(fd, "BOL  = %ld\n", item3);
+    psMetadataItemPrint(fd, "F32  = %g\n", item5);
+    psMetadataItemPrint(fd, "F64  = %g\n", item6);
+    psMetadataItemPrint(fd, "STR  = %s\n", item7);
+    psMetadataItemPrint(fd, "UNK  = \n", item8);
+    printFooter(stdout, "psMetadata", "Test F - Write metadata item to file", true);
+    fclose(fd);
+    fd = fopen("./tst_psMetadata05_OUT", "r");
+    if(fd == NULL) {
+        printf("ERROR: Couldn't open file for reading\n");
+    }
+    fscanf(fd, "S32 = %ld\n", &data);
+    if(data != 55) {
+        printf("ERROR: Data in file is not as expected. Value: %ld. Should be: 55.\n", data);
+    }
+    fscanf(fd, "BOL = %ld\n", &data);
+    if(data != 0) {
+        printf("ERROR: Data in file is not as expected. Value: %ld. Should be: 0.\n", data);
+    }
+    fscanf(fd, "F32 = %g\n", &fpdata);
+    if ( (fpdata <= 3.1) || (fpdata >= 3.2) ) {
+        printf("ERROR: Data in file is not as expected. Value: %g. Should be: 3.14.\n", fpdata);
+    }
+    fscanf(fd, "F64 = %g\n", &fpdata);
+    if ( (fpdata <= 6.2) || ( fpdata >= 6.3) ) {
+        printf("ERROR: Data in file is not as expected. Value: %g. Should be: 6.28.\n", fpdata);
+    }
+    fscanf(fd, "STR = %s\n", str);
+    if ( strcmp(str,"GNIRTS") != 0 ) {
+        printf("ERROR: Data is file is not as expected. Value: %s. Should be: GNIRTS.\n", str);
+    }
+    fclose(fd);
+
+    // Test G - Attempt to use null metadata with setIterator
+    printNegativeTestHeader(stdout,"psMetadata", "Test G - Attempt to use null metadata with setIterator",
+                            "Null metadata collection not allowed", 0);
+    psMetadataSetIterator(NULL, 0);
+    tmpList = metadata->list;
+    metadata->list = NULL;
+    psMetadataSetIterator(metadata,0);
+    metadata->list = tmpList;
+    printFooter(stdout, "psMetadata", "Test G - Attempt to use null metadata with setIterator", true);
+
+
+    // Test H - Attempt to use null metadata with getNext
+    printNegativeTestHeader(stdout,"psMetadata", "Test H - Attempt to use null metadata with getNext",
+                            "Null metadata collection not allowed", 0);
+    if( psMetadataGetNext(NULL, "myItem2", 0) != NULL ) {
+        psError(__func__,"psMetadataGetNext did not return null for null metadata.");
+        return 40;
+    }
+    tmpList = metadata->list;
+    metadata->list = NULL;
+    if ( psMetadataGetNext(metadata, "myItem2", 0) != NULL ) {
+        psError(__func__,"psMetadataGetNext did not return null for invalid metadata.");
+        return 41;
+    }
+    metadata->list = tmpList;
+
+    printFooter(stdout, "psMetadata", "Test H - Attempt to use null metadata with getNext", true);
+
+
+    // Test I - Attempt to use null metadata with getPrevious
+    printNegativeTestHeader(stdout,"psMetadata", "Test I - Attempt to use null metadata with getPrevious",
+                            "Null metadata collection not allowed", 0);
+    psMetadataGetPrevious(NULL, "myItem2", 0);
+    printFooter(stdout, "psMetadata", "Test I - Attempt to use null metadata with getPrevious", true);
+
+
+    // Test J - Attempt to use null file with itemPrint
+    printNegativeTestHeader(stdout,"psMetadata", "Test J - Attempt to use null file with itemPrint",
+                            "Null file descriptor not allowed", 0);
+    psMetadataItemPrint(NULL, "Item value: %ld", item2);
+    printFooter(stdout, "psMetadata", "Test J - Attempt to use null file with itemPrint", true);
+
+
+    // Test K - Attempt to use null format with itemPrint
+    printNegativeTestHeader(stdout,"psMetadata", "Test K - Attempt to use null format with itemPrint",
+                            "Null format not allowed", 0);
+    psMetadataItemPrint(fd, NULL, item2);
+    printFooter(stdout, "psMetadata", "Test K - Attempt to use null format with itemPrint", true);
+
+
+    // Test L - Attempt to use null item with itemPrint
+    printNegativeTestHeader(stdout,"psMetadata", "Test L - Attempt to use null item with itemPrint",
+                            "Null metadata not allowed", 0);
+    psMetadataItemPrint(fd, "Item value: %ld", NULL);
+    printFooter(stdout, "psMetadata", "Test L - Attempt to use null item with itemPrint", true);
+
+
+    // Test M - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test M - Free psMetadata");
+    psFree(metadata);
+    psFree(item1);
+    psFree(item2);
+    psFree(item3);
+    psFree(item4);
+    psFree(item5);
+    psFree(item6);
+    psFree(item7);
+    psFree(item8);
+    if ( psMemCheckLeaks(0, NULL, stdout) != 0 ) {
+        psError(__func__,"Memory leaks detected.");
+        return 50;
+    }
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+        return 51;
+    }
+    printFooter(stdout, "psMetadata", "Test M - Free psMetadata", true);
+
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/astronomy/tst_psMetadata_06.c
===================================================================
--- /branches/rel3/psLib/test/astronomy/tst_psMetadata_06.c	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/tst_psMetadata_06.c	(revision 2163)
@@ -0,0 +1,144 @@
+
+/** @file  tst_psMetadata_06.c
+*
+*  @brief Test driver for psMetadata functions
+*
+*  This test driver contains the following tests for psMetadata:
+*     Test A - Allocate metadata and items
+*     Test B - Add leaf node on top of existing leaf node
+*     Test C - Add leaf node to existing folder node
+*     Test D - Add folder node on top of existing leaf node
+*     Test E - Free psMetadata
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.3 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-10-12 01:54:00 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *item)
+{
+    printf("Key Name: %8s  ", item->name);
+    printf("Key Type: %2d  ", item->type);
+
+    switch (item->type ) {
+    case PS_META_BOOL:
+        printf("Key Value: %15d  ", item->data.B);
+        break;
+    case PS_META_S32:
+        printf("Key Value: %15d  ", item->data.S32);
+        break;
+    case PS_META_F32:
+        printf("Key Value: %15.3f  ", item->data.F32);
+        break;
+    case PS_META_F64:
+        printf("Key Value: %15.3f  ", item->data.F64);
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)item->data.V);
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        printf("Value: unknown ");
+        break;
+    default:
+        printf("Bad type: %d ", item->type);
+    }
+    printf("Key Comment: %s\n", item->comment);
+}
+
+
+int main( int argc, char* argv[] )
+{
+    psMetadataItem *item1a = NULL;
+    psMetadataItem *item1b = NULL;
+    psMetadataItem *item1c = NULL;
+    psMetadataItem *item2a = NULL;
+    psMetadataItem *item2b = NULL;
+    psMetadata *metadata = NULL;
+
+
+    // Test A - Allocate metadata and items
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Allocate metadata and items");
+    item1a = psMetadataItemAlloc("myItem1", PS_META_BOOL, "I am a boolean", true);
+    item1b = psMetadataItemAlloc("myItem1", PS_META_S32, "I am a signed integer", 111);
+    item1c = psMetadataItemAlloc("myItem1", PS_META_S32, "I am a signed integer", 222);
+    item2a = psMetadataItemAlloc("myItem2", PS_META_S32, "I am a signed integer", 333);
+    item2b = psMetadataItemAlloc("myItem2", PS_META_ITEM_SET, "I am a folder node", NULL);
+    metadata = psMetadataAlloc();
+    printMetadataItem(item1a);
+    printMetadataItem(item1b);
+    printMetadataItem(item1c);
+    printMetadataItem(item2a);
+    printMetadataItem(item2b);
+    printFooter(stdout, "psMetadata", "Test A - Allocate metadata and items", true);
+
+
+    // Test B - Add leaf node on top of existing leaf node
+    printPositiveTestHeader(stdout, "psMetadata", "Test B - Add leaf node on top of existing leaf node");
+    if( ! psMetadataAddItem(metadata, item1a, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem returned false for adding a node top.");
+        return 20;
+    }
+    if ( ! psMetadataAddItem(metadata, item1b, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem returned false for adding a node top.");
+        return 21;
+    }
+
+    printFooter(stdout, "psMetadata", "Test B - Add leaf node on top of existing leaf node", true);
+
+
+    // Test C - Add leaf node to existing folder node
+    printPositiveTestHeader(stdout, "psMetadata", "Test C - Add leaf node to existing folder node");
+    if ( ! psMetadataAddItem(metadata, item1c, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem return false for adding a not to existing node.");
+        return 22;
+    }
+    printFooter(stdout, "psMetadata", "Test C - Add leaf node to existing folder node", true);
+
+
+    // Test D - Add folder node on top of existing leaf node
+    printPositiveTestHeader(stdout, "psMetadata", "Test D - Add folder node on top of existing leaf node");
+    if ( ! psMetadataAddItem(metadata, item2a, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem returned false for adding a node to existing leaf node.");
+        return 23;
+    }
+    if ( ! psMetadataAddItem(metadata, item2b, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem returned false for adding a nod to existing leaf node.");
+        return 24;
+    }
+    printFooter(stdout, "psMetadata", "Test D - Add folder node on top of existing leaf node", true);
+
+
+    // Test E - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test E - Free psMetadata");
+    psFree(item1a);
+    psFree(item1b);
+    psFree(item1c);
+    psFree(item2a);
+    psFree(item2b);
+    psFree(metadata);
+    if ( psMemCheckLeaks(0, NULL, stdout) != 0 ) {
+        psError(__func__,"Memory leaks detected.");
+        return 25;
+    }
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test E - Free psMetadata", true);
+
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/astronomy/tst_psTime_01.c
===================================================================
--- /branches/rel3/psLib/test/astronomy/tst_psTime_01.c	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/tst_psTime_01.c	(revision 2163)
@@ -0,0 +1,207 @@
+/** @file  tst_psTime_01.c
+ *
+ *  @brief Test driver for psTime functions
+ *
+ *  This test driver contains the following tests for psTime:
+ *     A) Get current TAI time
+ *     B) Print test time
+ *     C) Convert psTime to ISO time
+ *     D) Convert ISO time to psTime
+ *     E) Convert psTime to UTC time
+ *     F) Convert UTC time to psTime
+ *     G) Convert psTime to MJD time
+ *     H) Convert MJD time to psTime
+ *     I) Convert psTime to JD time
+ *     J) Convert JD time to psTime
+ *     K) Convert psTime to timeval time
+ *     L) Convert timeval time to psTime
+ *     M) Convert psTime to tm time
+ *     N) Convert tm time to psTime
+ *     O) Convert psTime time to LST
+ *     P) Free psMetadata
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.12 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-10-12 01:34:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+int main(int argc, char* argv[])
+{
+    psTime *testTime;
+    char *testString = "2004-07-21T18:22:24.272Z";
+
+    // Test time was taken at July 21, 2004 at 18:22:24.272044
+    testTime = (psTime*)psAlloc(sizeof(psTime));
+    testTime->sec = 1090434144;
+    testTime->usec = 272044;
+    testTime->type = PS_TIME_TAI;
+
+    // Test A - Get current TAI time
+    printPositiveTestHeader(stdout,"psTime", "Get current TAI time");
+    psTime *timeA = NULL;
+    timeA = psTimeGetTime(PS_TIME_TAI);
+    psFree(timeA);
+    printFooter(stdout, "psTime", "Get current TAI time", true);
+
+
+    // Test B - Print test time
+    printPositiveTestHeader(stdout,"psTime", "Print test time");
+    printf("Test time: Seconds = %ld Microseconds = %ld\n", (long)testTime->sec, (long)testTime->usec);
+    printFooter(stdout, "psTime", "Print test time", true);
+
+
+    // Test C - Convert psTime to ISO time
+    printPositiveTestHeader(stdout,"psTime", "Convert psTime to ISO time");
+    char *isoString;
+    isoString = psTimeToISOTime(testTime);
+    printf("%s\n", isoString);
+    if(strncmp(isoString, testString, 256)) {
+        printf("ERROR - ISO string incorrect\n");
+        printf("Returned: %s\n", isoString);
+    }
+    printFooter(stdout, "psTime", "Convert psTime to ISO time", true);
+
+
+    // Test D - Convert ISO time to psTime
+    printPositiveTestHeader(stdout,"psTime", "Convert ISO time to psTime");
+    psTime *timeD = NULL;
+    timeD = psTimeFromISOTime(isoString);
+    printf("psTime: Seconds = %ld Microseconds = %d\n", (long)timeD->sec, (psU32)timeD->usec);
+    psFree(isoString);
+    psFree(timeD);
+    printFooter(stdout, "psTime", "Convert ISO time to psTime", true);
+
+
+    // Test E - Convert TAI to UTC time
+    printPositiveTestHeader(stdout,"psTime", "Convert psTime time to UTC time");
+    psTime *timeE = NULL;
+    timeE = (psTime*)psAlloc(sizeof(psTime));
+    timeE->sec = 1090434144;
+    timeE->usec = 272044;
+    timeE->type = PS_TIME_TAI;
+    timeE = psTimeConvert(timeE, PS_TIME_UTC);
+    psFree(timeE);
+    printf("psTime: Seconds = %ld Microseconds = %d\n", (long)timeE->sec, (psU32)timeE->usec);
+    printFooter(stdout, "psTime", "Convert psTime time to UTC time", true);
+
+
+    // Test F - Convert UTC time to psTime
+    printPositiveTestHeader(stdout,"psTime", "Convert UTC time to psTime");
+    psTime *timeF = NULL;
+    timeF = (psTime*)psAlloc(sizeof(psTime));
+    timeF->sec = 1090434112;
+    timeF->usec = 272044;
+    timeF->type = PS_TIME_UTC;
+    timeF = psTimeConvert(timeF, PS_TIME_TAI);
+    psFree(timeF);
+    printf("psTime: Seconds = %ld Microseconds = %d\n", (long)timeF->sec, (psU32)timeF->usec);
+    printFooter(stdout, "psTime", "Convert UTC time to psTime", true);
+
+
+    // Test G - Convert psTime to MJD time
+    printPositiveTestHeader(stdout,"psTime", "Convert psTime to MJD time");
+    double mjdTime = 0.0;
+    mjdTime = psTimeToMJD(testTime);
+    printf("MJD = %f\n", mjdTime);
+    printFooter(stdout, "psTime", "Convert psTime to MJD time", true);
+
+
+    // Test H - Convert MJD time to psTime
+    printPositiveTestHeader(stdout,"psTime", "Convert MJD time to psTime");
+    psTime *timeH = NULL;
+    timeH = psTimeFromMJD(mjdTime);
+    printf("psTime: Seconds = %ld Microseconds = %d\n", (long)timeH->sec, (psU32)timeH->usec);
+    psFree(timeH);
+    printFooter(stdout, "psTime", "Convert MJD time to psTime", true);
+
+
+    // Test I - Convert psTime to JD time
+    printPositiveTestHeader(stdout,"psTime", "Convert psTime to JD time");
+    double jdTime = 0.0;
+    jdTime = psTimeToJD(testTime);
+    printf("JD = %f\n", jdTime);
+    printFooter(stdout, "psTime", "Convert psTime to JD time", true);
+
+
+    // Test J - Convert JD time to psTime
+    printPositiveTestHeader(stdout,"psTime", "Convert JD time to psTime");
+    psTime *timeJ = NULL;
+    timeJ = psTimeFromJD(jdTime);
+    printf("psTime: Seconds = %ld Microseconds = %d\n", (long)timeJ->sec, (psU32)timeJ->usec);
+    psFree(timeJ);
+    printFooter(stdout, "psTime", "Convert JD time to psTime", true);
+
+
+    // Test K - Convert psTime to timeval time
+    printPositiveTestHeader(stdout,"psTime", "Convert psTime to timeval time");
+    struct timeval timevalTime;
+    timevalTime = psTimeToTimeval(testTime);
+    printf("timevalTime: Seconds = %ld Microseconds = %ld\n", (long)timevalTime.tv_sec, (long)timevalTime.tv_usec);
+    printFooter(stdout, "psTime", "Convert psTime to timeval time", true);
+
+
+    // Test L - Convert timeval time to psTime
+    printPositiveTestHeader(stdout,"psTime", "Convert timeval time to psTime");
+    psTime *timeL = NULL;
+    timeL = psTimeFromTimeval(&timevalTime);
+    printf("psTime: Seconds = %ld Microseconds = %d\n", (long)timeL->sec, (psU32)timeL->usec);
+    psFree(timeL);
+    printFooter(stdout, "psTime", "Convert timeval time to psTime", true);
+
+
+    // Test M - Convert psTime to tm time
+    printPositiveTestHeader(stdout,"psTime", "Convert psTime to tm time");
+    struct tm *tmTime;
+    tmTime = psTimeToTM(testTime);
+    printf("tmTime:\n");
+    printf("tmTime->tm_year = %d\n", tmTime->tm_year);
+    printf("tmTime->tm_mon = %d\n", tmTime->tm_mon);
+    printf("tmTime->tm_mday = %d\n", tmTime->tm_mday);
+    printf("tmTime->tm_hour = %d\n", tmTime->tm_hour);
+    printf("tmTime->tm_min = %d\n", tmTime->tm_min);
+    printf("tmTime->tm_sec = %d\n", tmTime->tm_sec);
+    printFooter(stdout, "psTime", "Convert psTime to tm time", true);
+
+
+    // Test N - Convert tm time to psTime
+    printPositiveTestHeader(stdout, "psTime", "Convert tm time to psTime");
+    psTime *timeN = NULL;
+    timeN = psTimeFromTM(tmTime);
+    printf("psTime: Seconds = %ld Microseconds = %d\n", (long)timeN->sec, (psU32)timeN->usec);
+    psFree(timeN);
+    psFree(tmTime);
+    printFooter(stdout, "psTime", "Convert tm time to psTime", true);
+
+
+    // Test O - psTime to LST
+    printPositiveTestHeader(stdout, "psTime", "Convert psTime time to LST");
+    char *testString2 = "2004-09-10T1:00:00.00Z";
+    psTime* testTime2 = NULL;
+    testTime2 = psTimeFromISOTime(testString2);
+    double dblTime = psTimeToLST(testTime2, 1);
+    printf("LST (rad): %lf\n", dblTime);
+    psFree(testTime2);
+    printFooter(stdout, "psTime", "Convert psTime time to LST", true);
+
+
+    // Test P - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test P - Free psMetadata");
+    psFree(testTime);
+    psMemCheckLeaks(0, NULL, stdout);
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test P - Free psMetadata", true);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/astronomy/tst_psTime_02.c
===================================================================
--- /branches/rel3/psLib/test/astronomy/tst_psTime_02.c	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/tst_psTime_02.c	(revision 2163)
@@ -0,0 +1,52 @@
+/** @file  tst_psTime_02.c
+ *
+ *  @brief Test driver for psTime functions
+ *
+ *  This test driver contains the following tests for psTime:
+ *     A) Incorrect ISO time data
+ *     B) Attempt to use null timeval
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-10-12 01:34:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc, char* argv[])
+{
+
+    // Test A - Incorrect ISO time data
+    printNegativeTestHeader(stdout,"psTime", "Incorrect ISO time data", "Time not allowed", 0);
+    psTimeFromISOTime("2004-99-21T18:22:24.272Z");
+    psTimeFromISOTime("2004-07-99T18:22:24.272Z");
+    psTimeFromISOTime("2004-07-21T99:22:24.272Z");
+    psTimeFromISOTime("2004-07-21T18:99:24.272Z");
+    psTimeFromISOTime("2004-07-21T18:22:99.272Z");
+    psTimeFromISOTime("2004-07-21T18:22:24.-999Z");
+    printFooter(stdout, "psTime", "Incorrect ISO time data", true);
+
+
+    // Test B - Attempt to use null timeval
+    printNegativeTestHeader(stdout,"psTime", "Attempt to use null timeval",
+                            "Null value for timeval arg not allowed", 0);
+    psTimeFromTimeval(NULL);
+    printFooter(stdout, "psTime", "Attempt to use null timeval", true);
+
+
+    // Test C - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test C - Free psMetadata");
+    psMemCheckLeaks(0, NULL, stdout);
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test C - Free psMetadata", true);
+    return 0;
+}
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psAstrometry.stderr
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psAstrometry.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psAstrometry.stderr	(revision 2163)
@@ -0,0 +1,54 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psAstrometry.c                                         *
+*            TestPoint: psImage{psExposureAlloc}                                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImage{psExposureAlloc} | tst_psAstrometry.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psAstrometry.c                                         *
+*            TestPoint: psImage{psObservatoryAlloc}                                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImage{psObservatoryAlloc} | tst_psAstrometry.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psAstrometry.c                                         *
+*            TestPoint: psImage{psFPAAlloc}                                        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImage{psFPAAlloc} | tst_psAstrometry.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psAstrometry.c                                         *
+*            TestPoint: psImage{psChipAlloc}                                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImage{psChipAlloc} | tst_psAstrometry.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psAstrometry.c                                         *
+*            TestPoint: psImage{psCellAlloc}                                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImage{psCellAlloc} | tst_psAstrometry.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psAstrometry.c                                         *
+*            TestPoint: psImage{psReadoutAlloc}                                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImage{psReadoutAlloc} | tst_psAstrometry.c)
+
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psMetadataIO.stderr
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psMetadataIO.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psMetadataIO.stderr	(revision 2163)
@@ -0,0 +1,44 @@
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    Failed to parse value. Value: 9876.54qqq32 Line 90: xPosition    F64          9876.54qqq32
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    Null value not allowed. Line 96: yPosition    F64          
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    Invalid psMetadataType. Type: 99.999 Line 102: zPosition       99.999          
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    More than one * charecter not allowed. Line 108: aPosition   **          
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    More than one @ charecter not allowed. Line 114: @@bPosition     F64     22.33             
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    Illegal character. Character:~ Line 120: range     F64     140.0 ~             
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    Failed to parse value. Value: 9876.54qqq32 Line 90: xPosition    F64          9876.54qqq32
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    Null value not allowed. Line 96: yPosition    F64          
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    Invalid psMetadataType. Type: 99.999 Line 102: zPosition       99.999          
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    More than one * charecter not allowed. Line 108: aPosition   **          
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    More than one @ charecter not allowed. Line 114: @@bPosition     F64     22.33             
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    Illegal character. Character:~ Line 120: range     F64     140.0 ~             
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    Overwrite for name not allowed. Name: speed. Line 128: speed     F32     66.66
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    Failed to parse value. Value: 9876.54qqq32 Line 90: xPosition    F64          9876.54qqq32
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    Null value not allowed. Line 96: yPosition    F64          
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    Invalid psMetadataType. Type: 99.999 Line 102: zPosition       99.999          
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    More than one * charecter not allowed. Line 108: aPosition   **          
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    More than one @ charecter not allowed. Line 114: @@bPosition     F64     22.33             
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    Illegal character. Character:~ Line 120: range     F64     140.0 ~             
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    Overwrite for name not allowed. Name: speed. Line 128: speed     F32     66.66
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    Null fileName not allowed
+<DATE><TIME>|<HOST>|E|psMetadataParseConfig
+    Couldn't open file. Name: abcedfg
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psMetadataIO.stdout
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psMetadataIO.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psMetadataIO.stdout	(revision 2163)
@@ -0,0 +1,176 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadataIO.c                                         *
+*            TestPoint: psMetadata{Test A - Read config file with overwrite set true} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Failed lines: 6 Expected: 6
+
+Contents of metadata list:
+ Key Name:       pi  Key Type:  4  Key Value:           3.142  Key Comment: Definition of pi
+ Key Name: altitude  Key Type:  2  Key Value:           10000  Key Comment: 
+ Key Name:     time  Key Type:  3  Key Value:        1234.568  Key Comment: 
+ Key Name:   myBool  Key Type:  1  Key Value:               0  Key Comment: F, f, 0, T, t, 1 are also acceptable
+ Key Name:   title1  Key Type:  5  Key Value:     Hello world  Key Comment: This is a comment for the string value
+ Key Name:   title2  Key Type:  5  Key Value:  Good bye world  Key Comment: STRING or STR may be used as the string type
+ Key Name:   primes  Key Type:  6  Key Value: 2 3 5 7 11 13 17 Key Comment: These are prime numbers
+ Key Name: negatives  Key Type:  6  Key Value: -1 -2 -3 -4 -5 -6 -7 Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:            This  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:              is  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:              an  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:            ugly  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:         comment  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:             but  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:           still  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:           valid  Key Comment: 
+ Key Name:    speed  Key Type:  3  Key Value:          66.660  Key Comment: 
+
+Contents of metadata table:
+ Key Name:  comment  Key Type:  0  Key Value:                  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:            This  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:              is  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:              an  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:            ugly  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:         comment  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:             but  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:           still  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:           valid  Key Comment: 
+ Key Name:   title2  Key Type:  5  Key Value:  Good bye world  Key Comment: STRING or STR may be used as the string type
+ Key Name:     time  Key Type:  3  Key Value:        1234.568  Key Comment: 
+ Key Name: negatives  Key Type:  6  Key Value: -1 -2 -3 -4 -5 -6 -7 Key Comment: 
+ Key Name:       pi  Key Type:  4  Key Value:           3.142  Key Comment: Definition of pi
+ Key Name:   myBool  Key Type:  1  Key Value:               0  Key Comment: F, f, 0, T, t, 1 are also acceptable
+ Key Name:   primes  Key Type:  6  Key Value: 2 3 5 7 11 13 17 Key Comment: These are prime numbers
+ Key Name: altitude  Key Type:  2  Key Value:           10000  Key Comment: 
+ Key Name:    speed  Key Type:  3  Key Value:          66.660  Key Comment: 
+ Key Name:   title1  Key Type:  5  Key Value:     Hello world  Key Comment: This is a comment for the string value
+
+---> TESTPOINT PASSED (psMetadata{Test A - Read config file with overwrite set true} | tst_psMetadataIO.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadataIO.c                                         *
+*            TestPoint: psMetadata{Test B - Read config file with overwrite set false} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Failed lines: 7 Expected: 7
+Contents of metadata list:
+ Key Name:       pi  Key Type:  4  Key Value:           3.142  Key Comment: Definition of pi
+ Key Name: altitude  Key Type:  2  Key Value:           10000  Key Comment: 
+ Key Name:     time  Key Type:  3  Key Value:        1234.568  Key Comment: 
+ Key Name:   myBool  Key Type:  1  Key Value:               0  Key Comment: F, f, 0, T, t, 1 are also acceptable
+ Key Name:   title1  Key Type:  5  Key Value:     Hello world  Key Comment: This is a comment for the string value
+ Key Name:   title2  Key Type:  5  Key Value:  Good bye world  Key Comment: STRING or STR may be used as the string type
+ Key Name:   primes  Key Type:  6  Key Value: 2 3 5 7 11 13 17 Key Comment: These are prime numbers
+ Key Name: negatives  Key Type:  6  Key Value: -1 -2 -3 -4 -5 -6 -7 Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:            This  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:              is  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:              an  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:            ugly  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:         comment  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:             but  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:           still  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:           valid  Key Comment: 
+ Key Name:    speed  Key Type:  3  Key Value:          55.550  Key Comment: 
+
+Contents of metadata table:
+ Key Name:  comment  Key Type:  0  Key Value:                  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:            This  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:              is  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:              an  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:            ugly  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:         comment  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:             but  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:           still  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:           valid  Key Comment: 
+ Key Name:   title2  Key Type:  5  Key Value:  Good bye world  Key Comment: STRING or STR may be used as the string type
+ Key Name:     time  Key Type:  3  Key Value:        1234.568  Key Comment: 
+ Key Name: negatives  Key Type:  6  Key Value: -1 -2 -3 -4 -5 -6 -7 Key Comment: 
+ Key Name:       pi  Key Type:  4  Key Value:           3.142  Key Comment: Definition of pi
+ Key Name:   myBool  Key Type:  1  Key Value:               0  Key Comment: F, f, 0, T, t, 1 are also acceptable
+ Key Name:   primes  Key Type:  6  Key Value: 2 3 5 7 11 13 17 Key Comment: These are prime numbers
+ Key Name: altitude  Key Type:  2  Key Value:           10000  Key Comment: 
+ Key Name:    speed  Key Type:  3  Key Value:          55.550  Key Comment: 
+ Key Name:   title1  Key Type:  5  Key Value:     Hello world  Key Comment: This is a comment for the string value
+
+---> TESTPOINT PASSED (psMetadata{Test B - Read config file with overwrite set false} | tst_psMetadataIO.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadataIO.c                                         *
+*            TestPoint: psMetadata{Test C - Read config file without auto-allocation of metadata} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Failed lines: 7 Expected: 7
+Contents of metadata list:
+ Key Name:       pi  Key Type:  4  Key Value:           3.142  Key Comment: Definition of pi
+ Key Name: altitude  Key Type:  2  Key Value:           10000  Key Comment: 
+ Key Name:     time  Key Type:  3  Key Value:        1234.568  Key Comment: 
+ Key Name:   myBool  Key Type:  1  Key Value:               0  Key Comment: F, f, 0, T, t, 1 are also acceptable
+ Key Name:   title1  Key Type:  5  Key Value:     Hello world  Key Comment: This is a comment for the string value
+ Key Name:   title2  Key Type:  5  Key Value:  Good bye world  Key Comment: STRING or STR may be used as the string type
+ Key Name:   primes  Key Type:  6  Key Value: 2 3 5 7 11 13 17 Key Comment: These are prime numbers
+ Key Name: negatives  Key Type:  6  Key Value: -1 -2 -3 -4 -5 -6 -7 Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:            This  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:              is  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:              an  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:            ugly  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:         comment  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:             but  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:           still  Key Comment: 
+ Key Name:  comment  Key Type:  5  Key Value:           valid  Key Comment: 
+ Key Name:    speed  Key Type:  3  Key Value:          55.550  Key Comment: 
+
+Contents of metadata table:
+ Key Name:  comment  Key Type:  0  Key Value:                  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:            This  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:              is  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:              an  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:            ugly  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:         comment  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:             but  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:           still  Key Comment: 
+    Key Name:  comment  Key Type:  5  Key Value:           valid  Key Comment: 
+ Key Name:   title2  Key Type:  5  Key Value:  Good bye world  Key Comment: STRING or STR may be used as the string type
+ Key Name:     time  Key Type:  3  Key Value:        1234.568  Key Comment: 
+ Key Name: negatives  Key Type:  6  Key Value: -1 -2 -3 -4 -5 -6 -7 Key Comment: 
+ Key Name:       pi  Key Type:  4  Key Value:           3.142  Key Comment: Definition of pi
+ Key Name:   myBool  Key Type:  1  Key Value:               0  Key Comment: F, f, 0, T, t, 1 are also acceptable
+ Key Name:   primes  Key Type:  6  Key Value: 2 3 5 7 11 13 17 Key Comment: These are prime numbers
+ Key Name: altitude  Key Type:  2  Key Value:           10000  Key Comment: 
+ Key Name:    speed  Key Type:  3  Key Value:          55.550  Key Comment: 
+ Key Name:   title1  Key Type:  5  Key Value:     Hello world  Key Comment: This is a comment for the string value
+
+---> TESTPOINT PASSED (psMetadata{Test C - Read config file without auto-allocation of metadata} | tst_psMetadataIO.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadataIO.c                                         *
+*            TestPoint: psMetadataIO{Test D - Attempt to use null fileName argument} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null failedLines not allowed                               *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test D - Attempt to use null fileName argument} | tst_psMetadataIO.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadataIO.c                                         *
+*            TestPoint: psMetadataIO{Test E - Attempt to open nonexistant file}    *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Error opening file                                         *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test E - Attempt to open nonexistant file} | tst_psMetadataIO.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadataIO.c                                         *
+*            TestPoint: psMetadata{Test F - Free psMetadata}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test F - Free psMetadata} | tst_psMetadataIO.c)
+
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_01.stderr
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_01.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_01.stderr	(revision 2163)
@@ -0,0 +1,14 @@
+<DATE><TIME>|<HOST>|E|psMetadataReadHeader
+    Null fileName not allowed
+<DATE><TIME>|<HOST>|E|psMetadataReadHeader
+    FITS error while opening file: missing.dat could not open the named file
+<DATE><TIME>|<HOST>|E|psMetadataReadHeader
+    Couldn't close FITS file. FITS error: NULL input pointer
+<DATE><TIME>|<HOST>|E|psMetadataReadHeader
+    Null extName and extNum = 0 not allowed
+<DATE><TIME>|<HOST>|E|psMetadataReadHeader
+    FITS error while locating header 22: tried to move past end of file
+<DATE><TIME>|<HOST>|E|psMetadataReadHeader
+    FITS error while locating header AARGH: illegal HDU number
+<DATE><TIME>|<HOST>|E|psMetadataReadHeader
+    If extName specified, extNum arguments should be -1.
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_01.stdout
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_01.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_01.stdout	(revision 2163)
@@ -0,0 +1,192 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_01.c                                        *
+*            TestPoint: psMetadata{Test A - Read 1st hdr from simple FITS file}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Contents of metadata list:
+ Key Name:   SIMPLE  Key Type:  1  Key Value:               1  Key Comment: file does conform to FITS standard
+ Key Name:   BITPIX  Key Type:  2  Key Value:               8  Key Comment: number of bits per data pixel
+ Key Name:    NAXIS  Key Type:  2  Key Value:               0  Key Comment: number of data axes
+ Key Name:  HISTORY  Key Type:  5  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+
+Contents of metadata table:
+ Key Name:    NAXIS  Key Type:  2  Key Value:               0  Key Comment: number of data axes
+ Key Name:   SIMPLE  Key Type:  1  Key Value:               1  Key Comment: file does conform to FITS standard
+ Key Name:   BITPIX  Key Type:  2  Key Value:               8  Key Comment: number of bits per data pixel
+ Key Name:  HISTORY  Key Type:  5  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+
+---> TESTPOINT PASSED (psMetadata{Test A - Read 1st hdr from simple FITS file} | tst_psMetadata_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_01.c                                        *
+*            TestPoint: psMetadata{Test B - Read 2nd hdr from complex FITS file}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Contents of metadata list:
+ Key Name: XTENSION  Key Type:  5  Key Value:      'IMAGE   '  Key Comment: IMAGE extension
+ Key Name:   BITPIX  Key Type:  2  Key Value:             -64  Key Comment: number of bits per data pixel
+ Key Name:    NAXIS  Key Type:  2  Key Value:               1  Key Comment: number of data axes
+ Key Name:   NAXIS1  Key Type:  2  Key Value:              64  Key Comment: length of data axis 1
+ Key Name:   PCOUNT  Key Type:  2  Key Value:               0  Key Comment: required keyword; must = 0
+ Key Name:   GCOUNT  Key Type:  2  Key Value:               1  Key Comment: required keyword; must = 1
+ Key Name:   BITPIX  Key Type:  2  Key Value:             -64  Key Comment: number of bits per data pixel
+ Key Name:  EXTNAME  Key Type:  5  Key Value:     'MY_DATA_1'  Key Comment: 
+ Key Name:  HISTORY  Key Type:  5  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+ Key Name:  HISTORY  Key Type:  5  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+ Key Name:  HISTORY  Key Type:  5  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+ Key Name:  HISTORY  Key Type:  5  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+
+Contents of metadata table:
+ Key Name:    NAXIS  Key Type:  2  Key Value:               1  Key Comment: number of data axes
+ Key Name:   NAXIS1  Key Type:  2  Key Value:              64  Key Comment: length of data axis 1
+ Key Name:   PCOUNT  Key Type:  2  Key Value:               0  Key Comment: required keyword; must = 0
+ Key Name: XTENSION  Key Type:  5  Key Value:      'IMAGE   '  Key Comment: IMAGE extension
+ Key Name:   BITPIX  Key Type:  0  Key Value:                  Key Comment: 
+    Key Name:   BITPIX  Key Type:  2  Key Value:             -64  Key Comment: number of bits per data pixel
+    Key Name:   BITPIX  Key Type:  2  Key Value:             -64  Key Comment: number of bits per data pixel
+ Key Name:   GCOUNT  Key Type:  2  Key Value:               1  Key Comment: required keyword; must = 1
+ Key Name:  HISTORY  Key Type:  0  Key Value:                  Key Comment: 
+    Key Name:  HISTORY  Key Type:  5  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+    Key Name:  HISTORY  Key Type:  5  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+    Key Name:  HISTORY  Key Type:  5  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+    Key Name:  HISTORY  Key Type:  5  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+ Key Name:  EXTNAME  Key Type:  5  Key Value:     'MY_DATA_1'  Key Comment: 
+
+---> TESTPOINT PASSED (psMetadata{Test B - Read 2nd hdr from complex FITS file} | tst_psMetadata_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_01.c                                        *
+*            TestPoint: psMetadata{Test C - Read named hdr from complex FITS file} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Contents of metadata list:
+ Key Name: XTENSION  Key Type:  5  Key Value:      'IMAGE   '  Key Comment: IMAGE extension
+ Key Name:   BITPIX  Key Type:  2  Key Value:             -64  Key Comment: number of bits per data pixel
+ Key Name:    NAXIS  Key Type:  2  Key Value:               1  Key Comment: number of data axes
+ Key Name:   NAXIS1  Key Type:  2  Key Value:              64  Key Comment: length of data axis 1
+ Key Name:   PCOUNT  Key Type:  2  Key Value:               0  Key Comment: required keyword; must = 0
+ Key Name:   GCOUNT  Key Type:  2  Key Value:               1  Key Comment: required keyword; must = 1
+ Key Name:  EXTNAME  Key Type:  5  Key Value:     'MY_DATA_2'  Key Comment: 
+ Key Name:  HISTORY  Key Type:  5  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+ Key Name:  HISTORY  Key Type:  5  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+
+Contents of metadata table:
+ Key Name:    NAXIS  Key Type:  2  Key Value:               1  Key Comment: number of data axes
+ Key Name:   NAXIS1  Key Type:  2  Key Value:              64  Key Comment: length of data axis 1
+ Key Name:   PCOUNT  Key Type:  2  Key Value:               0  Key Comment: required keyword; must = 0
+ Key Name: XTENSION  Key Type:  5  Key Value:      'IMAGE   '  Key Comment: IMAGE extension
+ Key Name:   GCOUNT  Key Type:  2  Key Value:               1  Key Comment: required keyword; must = 1
+ Key Name:   BITPIX  Key Type:  2  Key Value:             -64  Key Comment: number of bits per data pixel
+ Key Name:  HISTORY  Key Type:  0  Key Value:                  Key Comment: 
+    Key Name:  HISTORY  Key Type:  5  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+    Key Name:  HISTORY  Key Type:  5  Key Value:                  Key Comment: File modified by user 'harman' with fv  on 2004-08-04T<DATE>
+ Key Name:  EXTNAME  Key Type:  5  Key Value:     'MY_DATA_2'  Key Comment: 
+
+---> TESTPOINT PASSED (psMetadata{Test C - Read named hdr from complex FITS file} | tst_psMetadata_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_01.c                                        *
+*            TestPoint: psMetadata{Test D - Remove items with same name from all metadata} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Removed HISTORY from all metadata from prior test. Resulting metadata:
+
+Contents of metadata list:
+ Key Name: XTENSION  Key Type:  5  Key Value:      'IMAGE   '  Key Comment: IMAGE extension
+ Key Name:   BITPIX  Key Type:  2  Key Value:             -64  Key Comment: number of bits per data pixel
+ Key Name:    NAXIS  Key Type:  2  Key Value:               1  Key Comment: number of data axes
+ Key Name:   NAXIS1  Key Type:  2  Key Value:              64  Key Comment: length of data axis 1
+ Key Name:   PCOUNT  Key Type:  2  Key Value:               0  Key Comment: required keyword; must = 0
+ Key Name:   GCOUNT  Key Type:  2  Key Value:               1  Key Comment: required keyword; must = 1
+ Key Name:  EXTNAME  Key Type:  5  Key Value:     'MY_DATA_2'  Key Comment: 
+
+Contents of metadata table:
+ Key Name:    NAXIS  Key Type:  2  Key Value:               1  Key Comment: number of data axes
+ Key Name:   NAXIS1  Key Type:  2  Key Value:              64  Key Comment: length of data axis 1
+ Key Name:   PCOUNT  Key Type:  2  Key Value:               0  Key Comment: required keyword; must = 0
+ Key Name: XTENSION  Key Type:  5  Key Value:      'IMAGE   '  Key Comment: IMAGE extension
+ Key Name:   GCOUNT  Key Type:  2  Key Value:               1  Key Comment: required keyword; must = 1
+ Key Name:   BITPIX  Key Type:  2  Key Value:             -64  Key Comment: number of bits per data pixel
+ Key Name:  EXTNAME  Key Type:  5  Key Value:     'MY_DATA_2'  Key Comment: 
+
+---> TESTPOINT PASSED (psMetadata{Test D - Remove items with same name from all metadata} | tst_psMetadata_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_01.c                                        *
+*            TestPoint: psMetadata{Test E - Attempt to use null filename}          *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null fileName not allowed                                  *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test E - Attempt to use null filename} | tst_psMetadata_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_01.c                                        *
+*            TestPoint: psMetadata{Test F - Attempt to open nonexistant file}      *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: FITS error while opening file: missing.dat...Couldn't close FITS file... *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test F - Attempt to open nonexistant file} | tst_psMetadata_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_01.c                                        *
+*            TestPoint: psMetadata{Test G - Attempt to use two null inputs}        *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null extName and extNum = 0 not allowed                    *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test G - Attempt to use two null inputs} | tst_psMetadata_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_01.c                                        *
+*            TestPoint: psMetadata{Test H - Attempt to use bad extNum}             *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: FITS error while locating header 22: tried to move past end of file *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test H - Attempt to use bad extNum} | tst_psMetadata_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_01.c                                        *
+*            TestPoint: psMetadata{Test I - Attempt to use bad extName}            *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: FITS error while locating header AARGH: illegal HDU number *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test I - Attempt to use bad extName} | tst_psMetadata_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_01.c                                        *
+*            TestPoint: psMetadata{Test I1 - Read named hdr w/ invalid extnum}     *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: If extName specified, extNum should be -1.                 *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test C - Read named hdr from complex FITS file} | tst_psMetadata_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_01.c                                        *
+*            TestPoint: psMetadata{Test J - Free psMetadata}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test J - Free psMetadata} | tst_psMetadata_01.c)
+
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_02.stderr
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_02.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_02.stderr	(revision 2163)
@@ -0,0 +1,10 @@
+<DATE><TIME>|<HOST>|I|main
+    Following should produce error for null name.
+<DATE><TIME>|<HOST>|E|psMetadataItemAllocV
+    Null value for name not allowed
+<DATE><TIME>|<HOST>|E|psMetadataItemAllocV
+    Invalid psMetadataType: 7
+<DATE><TIME>|<HOST>|E|psMetadataAddItem
+    Null metadata collection not allowed
+<DATE><TIME>|<HOST>|E|psMetadataAddItem
+    Null metadata item not allowed
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_02.stdout
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_02.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_02.stdout	(revision 2163)
@@ -0,0 +1,76 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_02.c                                        *
+*            TestPoint: psMetadata{Test A - Allocate metadata items}               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Key Name:  myItem1  Key Type:  1  Key Value:               1  Key Comment: I am a boolean
+Key Name:  myItem2  Key Type:  2  Key Value:             111  Key Comment: I am a signed integer
+Key Name:  myItem3  Key Type:  3  Key Value:         222.222  Key Comment: I am a single precision floating point
+Key Name:  myItem4  Key Type:  4  Key Value:         333.333  Key Comment: I am a double precision floating point
+Key Name:  myItem5  Key Type:  5  Key Value:     HELLO WORLD  Key Comment: I am a string
+
+---> TESTPOINT PASSED (psMetadata{Test A - Allocate metadata items} | tst_psMetadata_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_02.c                                        *
+*            TestPoint: psMetadata{Test B - Attempt to create metadata item with null name} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null value for name not allowed                            *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test B - Attempt to create metadata item with null name} | tst_psMetadata_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_02.c                                        *
+*            TestPoint: psMetadata{Test C - Attempt to create metadata item with invalid type} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid psMetadataType: 6                                  *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test C - Attempt to create metadata item with invalid type} | tst_psMetadata_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_02.c                                        *
+*            TestPoint: psMetadata{Test D - Allocate metadata}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test D - Allocate metadata} | tst_psMetadata_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_02.c                                        *
+*            TestPoint: psMetadata{Test E - Attempt to add metadata item to null metadata} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null metadata collection not allowed                       *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test E - Attempt to add metadata item to null metadata} | tst_psMetadata_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_02.c                                        *
+*            TestPoint: psMetadata{Test F - Attempt to add null metadata item to metadata} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null metadata item not allowed                             *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test F - Attempt to add null metadata item to metadata} | tst_psMetadata_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_02.c                                        *
+*            TestPoint: psMetadata{Test G - Free psMetadata}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test G - Free psMetadata} | tst_psMetadata_02.c)
+
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_03.stderr
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_03.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_03.stderr	(revision 2163)
@@ -0,0 +1,20 @@
+<DATE><TIME>|<HOST>|E|psMetadataRemove
+    Null metadata collection not allowed
+<DATE><TIME>|<HOST>|E|psMetadataRemove
+    Couldn't find metadata item. Name: AARGH
+<DATE><TIME>|<HOST>|E|psMetadataRemove
+    Couldn't find metadata item in list. Index: 22
+<DATE><TIME>|<HOST>|E|psMetadataAddItem
+    Null metadata table not allowed
+<DATE><TIME>|<HOST>|E|psMetadataRemove
+    Null metadata table not allowed
+<DATE><TIME>|<HOST>|E|psMetadataAddItem
+    Null metadata list not allowed
+<DATE><TIME>|<HOST>|E|psMetadataRemove
+    Null metadata list not allowed
+<DATE><TIME>|<HOST>|E|psMetadataAddItem
+    Null key item not allowed
+<DATE><TIME>|<HOST>|E|psMetadataAddItem
+    Null metadata table not allowed
+<DATE><TIME>|<HOST>|E|psMetadataAdd
+    Couldn't add metadata item to metadata collection list. Name: errItem
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_03.stdout
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_03.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_03.stdout	(revision 2163)
@@ -0,0 +1,117 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_03.c                                        *
+*            TestPoint: psMetadata{Test A - Allocate metadata items}               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Key Name:  myItem1  Key Type:  1  Key Value:               1  Key Comment: I am a boolean
+Key Name:  myItem2  Key Type:  2  Key Value:              55  Key Comment: I am a integer
+Key Name:  myItem3  Key Type:  1  Key Value:               0  Key Comment: I am a boolean
+Key Name:  myItem4  Key Type:  2  Key Value:              66  Key Comment: I am a integer
+
+---> TESTPOINT PASSED (psMetadata{Test A - Allocate metadata items} | tst_psMetadata_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_03.c                                        *
+*            TestPoint: psMetadata{Test B - Remove items from metadata by name}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test B - Remove items from metadata by name} | tst_psMetadata_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_03.c                                        *
+*            TestPoint: psMetadata{Test C - Remove items from metadata by index}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test C - Remove items from metadata by index} | tst_psMetadata_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_03.c                                        *
+*            TestPoint: psMetadata{Test D - Attempt to use null metadata}          *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null metadata collection not allowed                       *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test D - Attempt to use null metadata} | tst_psMetadata_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_03.c                                        *
+*            TestPoint: psMetadata{Test E - Attempt to remove non-existant metadata item by name} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Couldn't find metadata item. Name: AARGH                   *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test E - Attempt to remove non-existant metadata item by name} | tst_psMetadata_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_03.c                                        *
+*            TestPoint: psMetadata{Test E - Attempt to remove non-existant metadata item by index} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Couldn't find metadata item in list. Index: 22             *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test E - Attempt to remove non-existant metadata item by index} | tst_psMetadata_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_03.c                                        *
+*            TestPoint: psMetadata{Test H - Attempt to add item to metadata w/o hash table} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Couldn't add item to invalid metadata structure.           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test H - Attempt to add item to invalid metadata w/o hash table} | tst_psMetadata_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_03.c                                        *
+*            TestPoint: psMetadata{Test J - Attempt to add item to metadata w/o link list} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Couldn't add item to invalid metadata structure.           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test J - Attempt to add item to invalid metadata w/o link list} | tst_psMetadata_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_03.c                                        *
+*            TestPoint: psMetadata{Test K - Attempt to add item with null name}    *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Couldn't add item with null name.                          *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test K - Attempt to add item with null name} | tst_psMetadata_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_03.c                                        *
+*            TestPoint: psMetadata{Test L - Attempt to add item to metadata w/o hash table} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Couldn't add item to invalid metadata structure.           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test L - Attempt to add item to invalid metadata w/o hash table} | tst_psMetadata_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_03.c                                        *
+*            TestPoint: psMetadata{Test G - Free psMetadata}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test G - Free psMetadata} | tst_psMetadata_03.c)
+
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_04.stderr
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_04.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_04.stderr	(revision 2163)
@@ -0,0 +1,12 @@
+<DATE><TIME>|<HOST>|E|psMetadataLookup
+    Null metadata collection not allowed
+<DATE><TIME>|<HOST>|E|psMetadataLookup
+    Null key name not allowed
+<DATE><TIME>|<HOST>|E|psMetadataGet
+    Null metadata collection not allowed
+<DATE><TIME>|<HOST>|E|psMetadataGet
+    Couldn't find metadata item with given index. Index: 22
+<DATE><TIME>|<HOST>|E|psMetadataLookup
+    Null metadata table not allowed
+<DATE><TIME>|<HOST>|E|psMetadataGet
+    Null metadata list not allowed
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_04.stdout
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_04.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_04.stdout	(revision 2163)
@@ -0,0 +1,119 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test A - Allocate metadata items}               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Key Name:  myItem1  Key Type:  1  Key Value:               1  Key Comment: I am a boolean
+Key Name:  myItem2  Key Type:  2  Key Value:              55  Key Comment: I am a integer
+Key Name:  myItem3  Key Type:  1  Key Value:               0  Key Comment: I am a boolean
+Key Name:  myItem4  Key Type:  2  Key Value:              66  Key Comment: I am a integer
+
+---> TESTPOINT PASSED (psMetadata{Test A - Allocate metadata items} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test B - Lookup metadata item by name}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Found item named myItem2
+
+---> TESTPOINT PASSED (psMetadata{Test B - Lookup metadata item by name} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test C - Attempt to use null metadata}          *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null metadata collection not allowed                       *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test C - Attempt to use null metadata} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test D - Attempt to use null key}               *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null key name not allowed                                  *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test D - Attempt to use null key} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test E - Attempt to lookup non-existant metadata item} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Couldn't find metadata item. Name: AARGH                   *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test E - Attempt to lookup non-existant metadata item} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test F - Lookup metadata item by index}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Found item named myItem4
+
+---> TESTPOINT PASSED (psMetadata{Test F - Lookup metadata item by index} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test G - Attempt to use null metadata}          *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null metadata collection not allowed                       *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test G - Attempt to use null metadata} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test H - Attempt to get non-existant metadata item} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Couldn't find metadata item with given index. Index: 22    *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test H - Attempt to get non-existant metadata item} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test J - Attemp to look up with an invalid metadata} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Lookup item with invalid metadata object.                  *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test J - Attempt to lookup an invalid metadata object.} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test K - Attemp to get item with an invalid metadata} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Get item with invalid metadata object.                     *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test K - Attempt to get item with  invalid metadata object.} | tst_psMetadata_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_04.c                                        *
+*            TestPoint: psMetadata{Test I - Free psMetadata}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test I - Free psMetadata} | tst_psMetadata_04.c)
+
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_05.stderr
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_05.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_05.stderr	(revision 2163)
@@ -0,0 +1,22 @@
+<DATE><TIME>|<HOST>|E|psMetadataItemAllocV
+    Invalid psMetadataType: 11
+<DATE><TIME>|<HOST>|E|psMetadataGetPrevious
+    Null metadata list not allowed
+<DATE><TIME>|<HOST>|E|psMetadataItemPrint
+     Invalid psMetadataType to print: 11
+<DATE><TIME>|<HOST>|E|psMetadataSetIterator
+    Null metadata collection not allowed
+<DATE><TIME>|<HOST>|E|psMetadataSetIterator
+    Null metadata list not allowed
+<DATE><TIME>|<HOST>|E|psMetadataGetNext
+    Null metadata collection not allowed
+<DATE><TIME>|<HOST>|E|psMetadataGetNext
+    Null metadata list not allowed
+<DATE><TIME>|<HOST>|E|psMetadataGetPrevious
+    Null metadata collection not allowed
+<DATE><TIME>|<HOST>|E|psMetadataItemPrint
+    Null file descriptor not allowed
+<DATE><TIME>|<HOST>|E|psMetadataItemPrint
+    Null format not allowed
+<DATE><TIME>|<HOST>|E|psMetadataItemPrint
+    Null metadata not allowed
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_05.stdout
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_05.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_05.stdout	(revision 2163)
@@ -0,0 +1,136 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_05.c                                        *
+*            TestPoint: psMetadata{Test A - Allocate metadata items}               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Key Name:  myItem1  Key Type:  1  Key Value:               1  Key Comment: I am a boolean
+Key Name:  myItem2  Key Type:  2  Key Value:              55  Key Comment: I am a integer
+Key Name:  myItem3  Key Type:  1  Key Value:               0  Key Comment: I am a boolean
+Key Name:  myItem4  Key Type:  2  Key Value:              66  Key Comment: I am a integer
+
+---> TESTPOINT PASSED (psMetadata{Test A - Allocate metadata items} | tst_psMetadata_05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_05.c                                        *
+*            TestPoint: psMetadata{Test B - Set iterator at second index}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test B - Set iterator at second index} | tst_psMetadata_05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_05.c                                        *
+*            TestPoint: psMetadata{Test C - Get next item at index}                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Found item named myItem1
+
+---> TESTPOINT PASSED (psMetadata{Test C - Get next item at index} | tst_psMetadata_05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_05.c                                        *
+*            TestPoint: psMetadata{Test D - Get next item at index and string}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Found item named myItem1
+
+---> TESTPOINT PASSED (psMetadata{Test D - Get next item at index and string} | tst_psMetadata_05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_05.c                                        *
+*            TestPoint: psMetadata{Test E - Get previous item at index}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Found item named myItem4
+
+---> TESTPOINT PASSED (psMetadata{Test E - Get previous item at index} | tst_psMetadata_05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_05.c                                        *
+*            TestPoint: psMetadata{Test F - Write metadata item to file}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test F - Write metadata item to file} | tst_psMetadata_05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_05.c                                        *
+*            TestPoint: psMetadata{Test G - Attempt to use null metadata with setIterator} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null metadata collection not allowed                       *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test G - Attempt to use null metadata with setIterator} | tst_psMetadata_05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_05.c                                        *
+*            TestPoint: psMetadata{Test H - Attempt to use null metadata with getNext} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null metadata collection not allowed                       *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test H - Attempt to use null metadata with getNext} | tst_psMetadata_05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_05.c                                        *
+*            TestPoint: psMetadata{Test I - Attempt to use null metadata with getPrevious} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null metadata collection not allowed                       *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test I - Attempt to use null metadata with getPrevious} | tst_psMetadata_05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_05.c                                        *
+*            TestPoint: psMetadata{Test J - Attempt to use null file with itemPrint} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null file descriptor not allowed                           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test J - Attempt to use null file with itemPrint} | tst_psMetadata_05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_05.c                                        *
+*            TestPoint: psMetadata{Test K - Attempt to use null format with itemPrint} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null format not allowed                                    *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test K - Attempt to use null format with itemPrint} | tst_psMetadata_05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_05.c                                        *
+*            TestPoint: psMetadata{Test L - Attempt to use null item with itemPrint} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null metadata not allowed                                  *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test L - Attempt to use null item with itemPrint} | tst_psMetadata_05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_05.c                                        *
+*            TestPoint: psMetadata{Test M - Free psMetadata}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test M - Free psMetadata} | tst_psMetadata_05.c)
+
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_06.stdout
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_06.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psMetadata_06.stdout	(revision 2163)
@@ -0,0 +1,50 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_06.c                                        *
+*            TestPoint: psMetadata{Test A - Allocate metadata and items}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Key Name:  myItem1  Key Type:  1  Key Value:               1  Key Comment: I am a boolean
+Key Name:  myItem1  Key Type:  2  Key Value:             111  Key Comment: I am a signed integer
+Key Name:  myItem1  Key Type:  2  Key Value:             222  Key Comment: I am a signed integer
+Key Name:  myItem2  Key Type:  2  Key Value:             333  Key Comment: I am a signed integer
+Key Name:  myItem2  Key Type:  0  Bad type: 0 Key Comment: I am a folder node
+
+---> TESTPOINT PASSED (psMetadata{Test A - Allocate metadata and items} | tst_psMetadata_06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_06.c                                        *
+*            TestPoint: psMetadata{Test B - Add leaf node on top of existing leaf node} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test B - Add leaf node on top of existing leaf node} | tst_psMetadata_06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_06.c                                        *
+*            TestPoint: psMetadata{Test C - Add leaf node to existing folder node} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test C - Add leaf node to existing folder node} | tst_psMetadata_06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_06.c                                        *
+*            TestPoint: psMetadata{Test D - Add folder node on top of existing leaf node} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test D - Add folder node on top of existing leaf node} | tst_psMetadata_06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMetadata_06.c                                        *
+*            TestPoint: psMetadata{Test E - Free psMetadata}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test E - Free psMetadata} | tst_psMetadata_06.c)
+
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psTime_01.stdout
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psTime_01.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psTime_01.stdout	(revision 2163)
@@ -0,0 +1,164 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_01.c                                            *
+*            TestPoint: psTime{Get current TAI time}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Get current TAI time} | tst_psTime_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_01.c                                            *
+*            TestPoint: psTime{Print test time}                                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Test time: Seconds = 1090434144 Microseconds = 272044
+
+---> TESTPOINT PASSED (psTime{Print test time} | tst_psTime_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_01.c                                            *
+*            TestPoint: psTime{Convert psTime to ISO time}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+2004-07-21T<DATE>.272Z
+
+---> TESTPOINT PASSED (psTime{Convert psTime to ISO time} | tst_psTime_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_01.c                                            *
+*            TestPoint: psTime{Convert ISO time to psTime}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+psTime: Seconds = 1090434144 Microseconds = 272000
+
+---> TESTPOINT PASSED (psTime{Convert ISO time to psTime} | tst_psTime_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_01.c                                            *
+*            TestPoint: psTime{Convert psTime time to UTC time}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+psTime: Seconds = 1090434112 Microseconds = 272044
+
+---> TESTPOINT PASSED (psTime{Convert psTime time to UTC time} | tst_psTime_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_01.c                                            *
+*            TestPoint: psTime{Convert UTC time to psTime}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+psTime: Seconds = 1090434144 Microseconds = 272044
+
+---> TESTPOINT PASSED (psTime{Convert UTC time to psTime} | tst_psTime_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_01.c                                            *
+*            TestPoint: psTime{Convert psTime to MJD time}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+MJD = 53207.765559
+
+---> TESTPOINT PASSED (psTime{Convert psTime to MJD time} | tst_psTime_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_01.c                                            *
+*            TestPoint: psTime{Convert MJD time to psTime}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+psTime: Seconds = 1090434144 Microseconds = 272043
+
+---> TESTPOINT PASSED (psTime{Convert MJD time to psTime} | tst_psTime_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_01.c                                            *
+*            TestPoint: psTime{Convert psTime to JD time}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+JD = 2453208.265559
+
+---> TESTPOINT PASSED (psTime{Convert psTime to JD time} | tst_psTime_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_01.c                                            *
+*            TestPoint: psTime{Convert JD time to psTime}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+psTime: Seconds = 1090434144 Microseconds = 272048
+
+---> TESTPOINT PASSED (psTime{Convert JD time to psTime} | tst_psTime_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_01.c                                            *
+*            TestPoint: psTime{Convert psTime to timeval time}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+timevalTime: Seconds = 1090434144 Microseconds = 272044
+
+---> TESTPOINT PASSED (psTime{Convert psTime to timeval time} | tst_psTime_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_01.c                                            *
+*            TestPoint: psTime{Convert timeval time to psTime}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+psTime: Seconds = 1090434144 Microseconds = 272044
+
+---> TESTPOINT PASSED (psTime{Convert timeval time to psTime} | tst_psTime_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_01.c                                            *
+*            TestPoint: psTime{Convert psTime to tm time}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+tmTime:
+tmTime->tm_year = 104
+tmTime->tm_mon = 6
+tmTime->tm_mday = 21
+tmTime->tm_hour = 18
+tmTime->tm_min = 22
+tmTime->tm_sec = 24
+
+---> TESTPOINT PASSED (psTime{Convert psTime to tm time} | tst_psTime_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_01.c                                            *
+*            TestPoint: psTime{Convert tm time to psTime}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+psTime: Seconds = 1090434144 Microseconds = 0
+
+---> TESTPOINT PASSED (psTime{Convert tm time to psTime} | tst_psTime_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_01.c                                            *
+*            TestPoint: psTime{Convert psTime time to LST}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+LST (rad): 1.074588
+
+---> TESTPOINT PASSED (psTime{Convert psTime time to LST} | tst_psTime_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_01.c                                            *
+*            TestPoint: psMetadata{Test P - Free psMetadata}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test P - Free psMetadata} | tst_psTime_01.c)
+
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psTime_02.stderr
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psTime_02.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psTime_02.stderr	(revision 2163)
@@ -0,0 +1,14 @@
+<DATE><TIME>|<HOST>|E|psTimeFromISOTime
+    Month must have a value from 1 to 12. Value: 99
+<DATE><TIME>|<HOST>|E|psTimeFromISOTime
+    Day must have a value from 1 to 31. Value: 99
+<DATE><TIME>|<HOST>|E|psTimeFromISOTime
+    Hour must have a value from 0 to 23. Value: 99
+<DATE><TIME>|<HOST>|E|psTimeFromISOTime
+    Minute must have a value from 0 to 59. Value: 99
+<DATE><TIME>|<HOST>|E|psTimeFromISOTime
+    Second must have a value from 0 to 59. Value: 99
+<DATE><TIME>|<HOST>|E|psTimeFromISOTime
+    Millisecond must have a value from 0 to 999. Value: -999
+<DATE><TIME>|<HOST>|E|psTimeFromTimeval
+    NULL value not allowed
Index: /branches/rel3/psLib/test/astronomy/verified/tst_psTime_02.stdout
===================================================================
--- /branches/rel3/psLib/test/astronomy/verified/tst_psTime_02.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/astronomy/verified/tst_psTime_02.stdout	(revision 2163)
@@ -0,0 +1,31 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_02.c                                            *
+*            TestPoint: psTime{Incorrect ISO time data}                            *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Time not allowed                                           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Incorrect ISO time data} | tst_psTime_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_02.c                                            *
+*            TestPoint: psTime{Attempt to use null timeval}                        *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null value for timeval arg not allowed                     *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTime{Attempt to use null timeval} | tst_psTime_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTime_02.c                                            *
+*            TestPoint: psMetadata{Test C - Free psMetadata}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMetadata{Test C - Free psMetadata} | tst_psTime_02.c)
+
Index: /branches/rel3/psLib/test/collections/.cvsignore
===================================================================
--- /branches/rel3/psLib/test/collections/.cvsignore	(revision 2163)
+++ /branches/rel3/psLib/test/collections/.cvsignore	(revision 2163)
@@ -0,0 +1,31 @@
+temp
+Makefile
+tst_psBitSet_01
+tst_psBitSet_02
+tst_psBitSet_03
+tst_psBitSet_04
+tst_psBitSet_05
+tst_psBitSet_06
+tst_psBitSet_07
+tst_psBitSet_08
+tst_psImage
+tst_psSort_01
+tst_psSort_02
+tst_psSort_03
+tst_psSort_04
+tst_psVector_01
+tst_psVector_02
+tst_psVector_03
+tst_psList
+tst_psArray
+tst_psVector
+tst_psVectorSort_01
+tst_psVectorSort_02
+tst_psVectorSort_03
+tst_psVectorSort_04
+tst_psHash00
+tst_psHash01
+tst_psHash02
+tst_psHash03
+tst_psHash04
+tst_psBitSet
Index: /branches/rel3/psLib/test/collections/Makefile
===================================================================
--- /branches/rel3/psLib/test/collections/Makefile	(revision 2163)
+++ /branches/rel3/psLib/test/collections/Makefile	(revision 2163)
@@ -0,0 +1,56 @@
+################################################################################
+##
+##  Makefile:   test/collections
+##
+##  $Revision: 1.23 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-09-14 20:01:52 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+##
+###############################################################################
+
+ifndef prefix
+    export prefix=$(shell cd ../..;pwd)
+endif
+
+include ../../src/Makefile.Globals
+
+CFLAGS := -I../../include $(CFLAGS)
+LDFLAGS := -L../../lib -lpslib -lpstest $(LDFLAGS)
+
+TARGET = tst_psVector          \
+         tst_psArray           \
+         tst_psBitSet          \
+         tst_psVectorSort_01   \
+         tst_psVectorSort_02   \
+         tst_psVectorSort_03   \
+         tst_psVectorSort_04   \
+         tst_psList            \
+         tst_psHash00          \
+         tst_psHash01          \
+         tst_psHash02          \
+         tst_psHash03          \
+         tst_psHash04
+
+OBJS = $(addsuffix .o,$(TARGET))
+
+all: $(TARGET)
+
+clean:
+	@echo "    Deleting executable and binary files for 'test/collections'"
+	$(RM) $(OBJS)
+
+distclean: clean
+	$(RM) $(TARGET)
+
+install: $(testbindir) $(testbindir)/verified $(TARGET)
+	install $(TARGET) $(testbindir)
+	install verified/*.stderr verified/*.stdout $(testbindir)/verified
+
+$(testbindir):
+	mkdir -p $(testbindir)
+
+$(testbindir)/verified:
+	mkdir -p $(testbindir)/verified
+
+
Index: /branches/rel3/psLib/test/collections/tst_psArray.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psArray.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psArray.c	(revision 2163)
@@ -0,0 +1,155 @@
+/** @file  tst_psArray.c
+ *
+ *  @brief Test driver for psArray integer functions
+ *
+ *  This test driver contains the following tests for psArray test point 1:
+ *     A)  Create void pointer array
+ *     B)  Add data to void pointer array
+ *     C)  Reallocate void pointer array bigger
+ *     D)  Reallocate void pointer array smaller
+ *     E)  Free void pointer array
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.3 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-09-28 23:26:49 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include <math.h>
+
+#include "pslib.h"
+#include "psTest.h"
+
+typedef struct
+{
+    int x;
+    float y;
+}
+testStruct;
+
+
+int main(int argc,
+         char* argv[])
+{
+    // Create array of pointers
+    testStruct *mySt[10];
+
+
+    // Test A - Create void pointer array
+    printPositiveTestHeader(stdout,"psArray", "Create void pointer array");
+    psArray *psArr = psArrayAlloc(5);
+    if (psArr->nalloc != 5) {
+        psError(__func__,"psArray didn't have proper number of elements.");
+        return 1;
+    }
+    printFooter(stdout, "psArray", "Create void pointer array", true);
+
+
+    // Test B - Add data to void pointer array
+    printPositiveTestHeader(stdout, "psArray", "Add data to void pointer array");
+    for(int i = 0; i < 5; i++) {
+        testStruct *ts = psAlloc(sizeof(testStruct));
+        ts->x = 10*i;
+        ts->y = 10.1*i;
+        mySt[i] = ts;
+        psArr->data[i] = ts;
+        psMemIncrRefCounter(ts);
+    }
+
+    for(int i = 0; i < 5; i++) {
+        testStruct *ts = (testStruct*)psArr->data[i];
+        printf("ts[%d].x = %d ts[%d].y = %.2f\n", i, ts->x, i, ts->y);
+        if (fabsf(ts->x - 10*i) > 0.01f || fabsf(ts->y - 10.1*i) > 0.01f) {
+            psError(__func__,"Couldn't properly get elements from array.");
+            return 2;
+        }
+    }
+    printf("array size = %d\n", psArr->nalloc);
+    if (psArr->nalloc != 5) {
+        psError(__func__,"Array Size wrong");
+        return 3;
+    }
+    printf("array population = %d\n", psArr->n);
+    if (psArr->n != 5) {
+        psError(__func__,"Array population wrong");
+        return 4;
+    }
+    printFooter(stdout, "psArray", "Add data to void pointer array", true);
+
+
+    // Test C - Reallocate void pointer array bigger
+    printPositiveTestHeader(stdout,"psArray", "Reallocate void pointer array bigger");
+    psArr = psArrayRealloc(psArr,10);
+    printf("Adding more elements to void pointer array...\n");
+    for(int i = 5; i < 10; i++) {
+        testStruct *ts = psAlloc(sizeof(testStruct));
+        ts->x = 10*i;
+        ts->y = 10.1*i;
+        mySt[i] = ts;
+        psArr->data[i] = ts;
+        psArr->n++;
+        psMemIncrRefCounter(ts);
+    }
+    for(int i = 0; i < 10; i++) {
+        testStruct *ts = (testStruct*)psArr->data[i];
+        printf("ts[%d].x = %d ts[%d].y = %.2f\n", i, ts->x, i, ts->y);
+        if (fabsf(ts->x - 10*i) > 0.01f || fabsf(ts->y - 10.1*i) > 0.01f) {
+            psError(__func__,"Couldn't properly get elements from array.");
+            return 5;
+        }
+    }
+    printf("array size = %d\n", psArr->nalloc);
+    if (psArr->nalloc != 10) {
+        psError(__func__,"Array Size wrong");
+        return 6;
+    }
+    printf("array population = %d\n", psArr->n);
+    if (psArr->n != 10) {
+        psError(__func__,"Array Population wrong");
+        return 7;
+    }
+    printFooter(stdout, "psArray", "Reallocate void pointer array bigger", true);
+
+
+    // Test D - Reallocate void pointer array smaller
+    printPositiveTestHeader(stdout,"psArray","Reallocate void pointer array smaller");
+    psArr = psArrayRealloc(psArr,3);
+    for(int i = 0; i < 3; i++) {
+        testStruct *ts = (testStruct*)psArr->data[i];
+        printf("ts[%d].x = %d ts[%d].y = %.2f\n", i, ts->x, i, ts->y);
+        if (fabsf(ts->x - 10*i) > 0.01f || fabsf(ts->y - 10.1*i) > 0.01f) {
+            psError(__func__,"Couldn't properly get elements from array.");
+            return 8;
+        }
+    }
+    printf("array size = %d\n", psArr->nalloc);
+    if (psArr->nalloc != 3) {
+        psError(__func__,"Array Size wrong");
+        return 9;
+    }
+    printf("array population = %d\n", psArr->n);
+    if (psArr->n != 3) {
+        psError(__func__,"Array Population wrong");
+        return 10;
+    }
+    printFooter(stdout, "psArray", "Reallocate integer void pointer smaller", true);
+
+
+    // Test E - Free void pointer array
+    printPositiveTestHeader(stdout, "psArray", "Free void pointer array");
+    psFree(psArr);
+    for(int i = 0; i < 10; i++) {
+        psFree(mySt[i]);
+    }
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psArray" ,"Free void pointer array", true);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/collections/tst_psBitSet.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psBitSet.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psBitSet.c	(revision 2163)
@@ -0,0 +1,647 @@
+/** @file  tst_psBitSet_01.c
+ *
+ *  @brief Test driver for psBitSet functions
+ *
+ *  This test driver contains the following tests for psBitSet test point 1:
+ *     A)  Create psBitSet
+ *     B)  Set bits
+ *     C)  Test bits
+ *     D)  Attempt to test negative bit
+ *     E)  Attempt to test bit to large
+ *     F)  Attempt to test bit in null BitSet
+ *     G)  Attempt to set negative bit
+ *     H)  Attempt to set bit to large
+ *     I)  Attempt to set bit in null BitSet
+ *     J)  Free psBitSet
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.1 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-09-14 20:01:52 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+static int testBitSet01a(void);
+static int testBitSet01b(void);
+static int testBitSet01c(void);
+static int testBitSet02(void);
+static int testBitSet03(void);
+static int testBitSet04(void);
+static int testBitSet05(void);
+static int testBitSet06(void);
+
+testDescription tests[] = {
+                              {testBitSet01a, 1, "psBitSetAlloc", 0, false},
+                              {testBitSet01b, 2, "psBitSetSet/psBitSetClear", 0, false},
+                              {testBitSet01c, 3, "psBitSetTest", 0, false},
+                              {testBitSet06, 4, "psBitSetOp", 0, false},
+                              {testBitSet02, 5, "psBitSetOp AND Operator", 0, false},
+                              {testBitSet03, 6, "psBitSetOp OR Operator", 0, false},
+                              {testBitSet04, 7, "psBitSetOp XOR Operator", 0, false},
+                              {testBitSet05, 8, "psBitSetNot", 0, false},
+
+                              {NULL}
+                          };
+
+
+int main( int argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psBitSet", tests, argc, argv ) );
+}
+
+int testBitSet01a(void)
+{
+    psErr* err;
+
+    // Test A - Create psBitSet
+    fprintf(stderr,"Creating psBitSet with 24 bits...\n");
+    psBitSet* bs = psBitSetAlloc(24);
+
+    if (bs == NULL) {
+        psAbort(__func__,"Failed to create a psBitSet");
+    }
+
+    if (bs->n != 3) {
+        psAbort(__func__,"Number of bytes for psBitSet incorrect (%d vs 3)",bs->n);
+    }
+
+    if (bs->bits[0] != 0 || bs->bits[1] != 0 || bs->bits[2] != 0) {
+        psAbort(__func__,"psBitSetAlloc didn't clear out the bits by default (%x%x%x).",
+                bs->bits[2],bs->bits[1],bs->bits[0]);
+    }
+
+    psFree(bs);
+
+    // Test A - Create psBitSet
+    fprintf(stderr,"Creating psBitSet with 25 bits...\n");
+    bs = psBitSetAlloc(25);
+
+    if (bs == NULL) {
+        psAbort("testBitSet01a","Failed to create a psBitSet with 25 bits");
+    }
+
+    if (bs->n != 4) {
+        psAbort("testBitSet01a","Number of bytes for psBitSet incorrect (%d vs 4)",bs->n);
+    }
+    psFree(bs);
+
+    psErrorClear();
+    psLogMsg(__func__,PS_LOG_INFO,"Following is an error.");
+    bs = psBitSetAlloc(-4);
+    if (bs != NULL) {
+        psAbort(__func__,"psBitSetAlloc returned something in case of a negative sized psBitSet.");
+    }
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psErrorStackPrint(stderr,"Error Stack:");
+        psAbort(__func__,"psBitSetAlloc didn't generate expected error with size = -4.");
+    }
+    psFree(err);
+
+    return 0;
+}
+
+int testBitSet01b(void)
+{
+    char *binOut = NULL;
+    psBitSet *tempBs = NULL;
+    psErr* err = NULL;
+
+    psBitSet* bs = psBitSetAlloc(24);
+
+    if (psBitSetTest(bs,0) ||
+            psBitSetTest(bs,2) ||
+            psBitSetTest(bs,23) ) {
+
+        psAbort("testBitSet01b","psBitSetAlloc failed to clear all bits at allocation.");
+    }
+
+    // Test B - Set bits
+    tempBs = bs;
+    fprintf(stderr,"Setting first bit...\n");
+    bs = psBitSetSet(bs, 0);
+    fprintf(stderr,"Setting third bit...\n");
+    bs = psBitSetSet(bs, 2);
+    fprintf(stderr,"Setting last bit...\n");
+    bs = psBitSetSet(bs, 23);
+    if(bs != tempBs) {
+        psAbort("testBitSet01b",
+                "Return pointer not equal to output argument pointer.");
+    }
+    if(bs->bits[0] != 0x05) {
+        psAbort(__func__,
+                "Unexpected value for first byte (%d vs 5).",
+                bs->bits[0]);
+    }
+
+
+    binOut = psBitSetToString(bs);
+    fprintf(stderr,"%s\n\n", binOut);
+    psFree(binOut);
+
+    // Test C - Test bits
+    if (! psBitSetTest(bs,0) ||
+            ! psBitSetTest(bs,2) ||
+            ! psBitSetTest(bs,23) ) {
+
+        psAbort("testBitSet01b","Failed to set a bit.");
+    }
+
+    fprintf(stderr,"Clearing first bit...\n");
+    bs = psBitSetClear(bs, 0);
+    fprintf(stderr,"Clearing third bit...\n");
+    bs = psBitSetClear(bs, 2);
+    fprintf(stderr,"Clearing last bit...\n");
+    bs = psBitSetClear(bs, 23);
+
+    binOut = psBitSetToString(bs);
+    fprintf(stderr,"%s\n\n", binOut);
+    psFree(binOut);
+
+
+    if (psBitSetTest(bs,0) ||
+            psBitSetTest(bs,2) ||
+            psBitSetTest(bs,23) ) {
+
+        psAbort("testBitSet01b","Failed to clear a bit.");
+    }
+
+    psLogMsg("testBitSet01b",PS_LOG_INFO,"Following should be an error");
+    psErrorClear();
+    psBitSetSet(bs, -4);
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psErrorStackPrint(stderr,"Error Stack:");
+        psAbort("testBitSet01c","psBitSetSet(bs, -4) didn't generate expected error.\n");
+    }
+    psFree(err);
+
+    psLogMsg("testBitSet01b",PS_LOG_INFO,"Following should be an error");
+    psErrorClear();
+    psBitSetSet(bs, 200);
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psErrorStackPrint(stderr,"Error Stack:");
+        psAbort("testBitSet01c","psBitSetSet(bs, 200) didn't generate expected error.\n");
+    }
+    psFree(err);
+
+    psLogMsg("testBitSet01b",PS_LOG_INFO,"Following should be an error");
+    psErrorClear();
+    psBitSetSet(NULL, 0);
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
+        psErrorStackPrint(stderr,"Error Stack:");
+        psAbort("testBitSet01c","psBitSetSet(NULL,0) didn't generate expected error.\n");
+    }
+    psFree(err);
+
+    psFree(bs);
+
+    return 0;
+}
+
+static int testBitSet01c(void)
+{
+    psBitSet* bs = psBitSetAlloc(24);
+    psErr* err = NULL;
+
+    fprintf(stderr,"Setting first bit...\n");
+    bs = psBitSetSet(bs, 0);
+    fprintf(stderr,"Setting third bit...\n");
+    bs = psBitSetSet(bs, 2);
+    fprintf(stderr,"Setting last bit...\n");
+    bs = psBitSetSet(bs, 23);
+
+    if (! psBitSetTest(bs,0) ||
+            ! psBitSetTest(bs,2) ||
+            ! psBitSetTest(bs,23) ) {
+
+        psAbort("testBitSet01c","Set bits returned false.");
+    }
+
+    psLogMsg("testBitSet01c",PS_LOG_INFO,"Following should be an error");
+    psErrorClear();
+    if(psBitSetTest(bs, -4)) {
+        psAbort("testBitSet01c","psBitSetTest returned true with negative bit position.\n");
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psErrorStackPrint(stderr,"Error Stack:");
+        psAbort("testBitSet01c","psBitSetTest(bs, -4) didn't generate proper error.\n");
+    }
+    psFree(err);
+
+    psLogMsg("testBitSet01c",PS_LOG_INFO,"Following should be an error");
+    psErrorClear();
+    if(psBitSetTest(bs, 200)) {
+        psAbort("testBitSet01c","psBitSetTest returned true with too-large bit position.\n");
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psErrorStackPrint(stderr,"Error Stack:");
+        psAbort("testBitSet01c","psBitSetTest(bs, 200) didn't generate proper error.\n");
+    }
+    psFree(err);
+
+    psLogMsg("testBitSet01c",PS_LOG_INFO,"Following should be an error");
+    psErrorClear();
+    if (psBitSetTest(NULL, 0)) {
+        psAbort("testBitSet01c","psBitSetTest returned true with NULL psBitSet.\n");
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
+        psErrorStackPrint(stderr,"Error Stack:");
+        psAbort("testBitSet01c","psBitSetTest(NULL, 0) didn't generate proper error.\n");
+    }
+    psFree(err);
+
+    psFree(bs);
+
+    return 0;
+}
+
+int testBitSet02()
+{
+    char *binOut1 = NULL;
+    char *binOut2 = NULL;
+    char *binOut3 = NULL;
+
+    psBitSet* bs1 = psBitSetAlloc(24);
+    psBitSet* bs2 = psBitSetAlloc(24);
+    psBitSet* and = psBitSetAlloc(24);
+    for(int i=0; i<24; i++) {
+        if ((i & 2) == 0) {
+            bs1 = psBitSetSet(bs1, i);
+        }
+        if ((i & 1) == 0) {
+            bs2 = psBitSetSet(bs2, i);
+        }
+        if (((i & 1) == 0) && ((i & 2) == 0) ) {
+            and = psBitSetSet(and, i);
+        }
+    }
+    binOut1 = psBitSetToString(bs1);
+    binOut2 = psBitSetToString(bs2);
+    binOut3 = psBitSetToString(and);
+    fprintf(stderr,"psBitSetOp input is %s, %s.  Truth is %s.\n",
+            binOut1,binOut2,binOut3);
+    psFree(binOut1);
+    psFree(binOut2);
+    psFree(binOut3);
+
+    // Test B - Perform binary AND with psBitSets
+    psLogMsg(__func__,PS_LOG_INFO,"Perform binary AND with psBitSets");
+    psBitSet* outbs = psBitSetAlloc(24);
+    outbs = psBitSetOp(outbs, bs1, "AND", bs2);
+    if (outbs == NULL) {
+        psAbort(__func__,"psBitSetOp returned a NULL result for AND operation");
+    }
+
+    for(int i=0; i<24; i++) {
+        bool truth = psBitSetTest(and,i);
+        bool res = psBitSetTest(outbs,i);
+        if ( res != truth) {
+            binOut1 = psBitSetToString(bs1);
+            binOut2 = psBitSetToString(bs2);
+            binOut3 = psBitSetToString(outbs);
+            psAbort(__func__,"psBitSetOp with AND operator failed.\nInput was %s, %s.  Output was %s",
+                    binOut1,binOut2,binOut3);
+        }
+    }
+    psFree(outbs);
+
+    // Test C - Perform binary AND and auto allocate output
+    psLogMsg(__func__,PS_LOG_INFO,"Perform binary AND and auto allocate output");
+    outbs = psBitSetOp(NULL, bs1, "AND", bs2);
+    if (outbs == NULL) {
+        psAbort(__func__,"psBitSetOp failed to create a new psBitSet for the result");
+    }
+    for(int i=0; i<24; i++) {
+        bool truth = psBitSetTest(and,i);
+        bool res = psBitSetTest(outbs,i);
+        if ( res != truth) {
+            binOut1 = psBitSetToString(bs1);
+            binOut2 = psBitSetToString(bs2);
+            binOut3 = psBitSetToString(outbs);
+            psAbort(__func__,"psBitSetOp with AND operator failed.\nInput was %s, %s.  Output was %s",
+                    binOut1,binOut2,binOut3);
+        }
+    }
+    psFree(outbs);
+
+    psFree(bs1);
+    psFree(bs2);
+    psFree(and);
+
+    return 0;
+}
+
+static int testBitSet03(void)
+{
+    char *binOut1 = NULL;
+    char *binOut2 = NULL;
+    char *binOut3 = NULL;
+
+    psBitSet* bs1 = psBitSetAlloc(24);
+    psBitSet* bs2 = psBitSetAlloc(24);
+    psBitSet* or = psBitSetAlloc(24);
+    for(int i=0; i<24; i++) {
+        if ((i/2) % 2) {
+            bs1 = psBitSetSet(bs1, i);
+        }
+        if ((i) % 2) {
+            bs2 = psBitSetSet(bs2, i);
+        }
+        if ( ((i/2) % 2) || ((i) % 2) ) {
+            or = psBitSetSet(or, i);
+        }
+    }
+
+    binOut1 = psBitSetToString(bs1);
+    binOut2 = psBitSetToString(bs2);
+    binOut3 = psBitSetToString(or);
+    fprintf(stderr,"psBitSetOp input is %s, %s.  Truth is %s.\n",
+            binOut1,binOut2,binOut3);
+    psFree(binOut1);
+    psFree(binOut2);
+    psFree(binOut3);
+
+    // Test B - Perform binary AND with psBitSets
+    psLogMsg(__func__,PS_LOG_INFO,"Perform binary OR with psBitSets");
+    psBitSet* outbs = psBitSetAlloc(24);
+    outbs = psBitSetOp(outbs, bs1, "OR", bs2);
+    if (outbs == NULL) {
+        psAbort(__func__,"psBitSetOp returned a NULL result for OR operation");
+    }
+
+    for(int i=0; i<24; i++) {
+        bool truth = psBitSetTest(or,i);
+        bool res = psBitSetTest(outbs,i);
+        if ( res != truth) {
+            binOut1 = psBitSetToString(bs1);
+            binOut2 = psBitSetToString(bs2);
+            binOut3 = psBitSetToString(outbs);
+            psAbort(__func__,"psBitSetOp with OR operator failed.\nInput was %s, %s.  Output was %s",
+                    binOut1,binOut2,binOut3);
+        }
+    }
+    psFree(outbs);
+
+    // Test C - Perform binary AND and auto allocate output
+    psLogMsg(__func__,PS_LOG_INFO,"Perform binary OR and auto allocate output");
+    outbs = psBitSetOp(NULL, bs1, "OR", bs2);
+    if (outbs == NULL) {
+        psAbort(__func__,"psBitSetOp failed to create a new psBitSet for the result");
+    }
+    for(int i=0; i<24; i++) {
+        bool truth = psBitSetTest(or,i);
+        bool res = psBitSetTest(outbs,i);
+        if ( res != truth) {
+            binOut1 = psBitSetToString(bs1);
+            binOut2 = psBitSetToString(bs2);
+            binOut3 = psBitSetToString(outbs);
+            psAbort(__func__,"psBitSetOp with OR operator failed.\nInput was %s, %s.  Output was %s",
+                    binOut1,binOut2,binOut3);
+        }
+    }
+    psFree(outbs);
+    outbs = NULL;
+
+    psFree(bs1);
+    psFree(bs2);
+    psFree(or);
+
+    return 0;
+}
+
+static int testBitSet04(void)
+{
+    char *binOut1 = NULL;
+    char *binOut2 = NULL;
+    char *binOut3 = NULL;
+
+    psBitSet* bs1 = psBitSetAlloc(24);
+    psBitSet* bs2 = psBitSetAlloc(24);
+    psBitSet* xor = psBitSetAlloc(24);
+    for(int i=0; i<24; i++) {
+        if ((i/2) % 2) {
+            bs1 = psBitSetSet(bs1, i);
+        }
+        if ((i) % 2) {
+            bs2 = psBitSetSet(bs2, i);
+        }
+        if ( ((i/2) % 2) != ((i) % 2) ) {
+            xor = psBitSetSet(xor, i);
+        }
+    }
+
+    binOut1 = psBitSetToString(bs1);
+    binOut2 = psBitSetToString(bs2);
+    binOut3 = psBitSetToString(xor);
+    fprintf(stderr,"psBitSetOp input is %s, %s.  Truth is %s.\n",
+            binOut1,binOut2,binOut3);
+    psFree(binOut1);
+    psFree(binOut2);
+    psFree(binOut3);
+
+    // Test B - Perform binary AND with psBitSets
+    psLogMsg(__func__,PS_LOG_INFO,"Perform binary XOR with psBitSets");
+    psBitSet* outbs = psBitSetAlloc(24);
+    outbs = psBitSetOp(outbs, bs1, "XOR", bs2);
+    if (outbs == NULL) {
+        psAbort(__func__,"psBitSetOp returned a NULL result for XOR operation");
+    }
+
+    for(int i=0; i<24; i++) {
+        bool truth = psBitSetTest(xor,i);
+        bool res = psBitSetTest(outbs,i);
+        if ( res != truth) {
+            binOut1 = psBitSetToString(bs1);
+            binOut2 = psBitSetToString(bs2);
+            binOut3 = psBitSetToString(outbs);
+            psAbort(__func__,"psBitSetOp with XOR operator failed.\nInput was %s, %s.  Output was %s",
+                    binOut1,binOut2,binOut3);
+        }
+    }
+    psFree(outbs);
+
+    // Test C - Perform binary AND and auto allocate output
+    psLogMsg(__func__,PS_LOG_INFO,"Perform binary XOR and auto allocate output");
+    outbs = psBitSetOp(NULL, bs1, "XOR", bs2);
+    if (outbs == NULL) {
+        psAbort(__func__,"psBitSetOp failed to create a new psBitSet for the result");
+    }
+    for(int i=0; i<24; i++) {
+        bool truth = psBitSetTest(xor,i);
+        bool res = psBitSetTest(outbs,i);
+        if ( res != truth) {
+            binOut1 = psBitSetToString(bs1);
+            binOut2 = psBitSetToString(bs2);
+            binOut3 = psBitSetToString(outbs);
+            psAbort(__func__,"psBitSetOp with XOR operator failed.\nInput was %s, %s.  Output was %s",
+                    binOut1,binOut2,binOut3);
+        }
+    }
+    psFree(outbs);
+    outbs = NULL;
+
+    psFree(bs1);
+    psFree(bs2);
+    psFree(xor);
+
+    return 0;
+}
+
+static int testBitSet05(void)
+{
+    char *binOut1 = NULL;
+    char *binOut2 = NULL;
+
+    psBitSet* bs1 = psBitSetAlloc(24);
+    psBitSet* not = psBitSetAlloc(24);
+    for(int i=0; i<24; i++) {
+        if (i % 2) {
+            bs1 = psBitSetSet(bs1, i);
+        }
+        if (i % 2 == 0) {
+            not = psBitSetSet(not, i);
+        }
+    }
+
+    binOut1 = psBitSetToString(bs1);
+    binOut2 = psBitSetToString(not);
+    fprintf(stderr,"psBitSetOp input is %s.  Truth is %s.\n",
+            binOut1,binOut2);
+    psFree(binOut1);
+    psFree(binOut2);
+
+    // Test B - Perform binary AND with psBitSets
+    psLogMsg(__func__,PS_LOG_INFO,"Perform binary NOT with psBitSets");
+    psBitSet* outbs = psBitSetAlloc(24);
+    outbs = psBitSetNot(outbs, bs1);
+    if (outbs == NULL) {
+        psAbort(__func__,"psBitSetOp returned a NULL result for NOT operation");
+    }
+
+    for(int i=0; i<24; i++) {
+        bool truth = psBitSetTest(not,i);
+        bool res = psBitSetTest(outbs,i);
+        if ( res != truth) {
+            binOut1 = psBitSetToString(bs1);
+            binOut2 = psBitSetToString(outbs);
+            psAbort(__func__,"psBitSetOp with NOT operator failed.\nInput was %s.  Output was %s",
+                    binOut1,binOut2);
+        }
+    }
+    psFree(outbs);
+
+    // Test C - Perform binary AND and auto allocate output
+    psLogMsg(__func__,PS_LOG_INFO,"Perform binary NOT and auto allocate output");
+    outbs = psBitSetNot(NULL, bs1);
+    if (outbs == NULL) {
+        psAbort(__func__,"psBitSetOp failed to create a new psBitSet for the result");
+    }
+    for(int i=0; i<24; i++) {
+        bool truth = psBitSetTest(not,i);
+        bool res = psBitSetTest(outbs,i);
+        if ( res != truth) {
+            binOut1 = psBitSetToString(bs1);
+            binOut2 = psBitSetToString(outbs);
+            psAbort(__func__,"psBitSetOp with NOT operator failed.\nInput was %s.  Output was %s",
+                    binOut1,binOut2);
+        }
+    }
+    psFree(outbs);
+    outbs = NULL;
+
+    psFree(bs1);
+    psFree(not);
+
+    return 0;
+}
+
+static int testBitSet06(void)
+{
+    psErr* err;
+
+    psBitSet* bs1 = psBitSetAlloc(24);
+    psBitSet* bs2 = psBitSetAlloc(40);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error");
+    psBitSet* outbs = psBitSetOp(NULL, bs1, "XOR", bs2);
+    if (outbs != NULL) {
+        psAbort(__func__,"psBitSetOp did not return a NULL result when input sizes differ");
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_SIZE) {
+        psErrorStackPrint(stderr,"Error Stack:");
+        psAbort(__func__,"psBitSetOp didn't generate expected error with operands' sizes differed.");
+    }
+    psFree(err);
+    psFree(bs1);
+    psFree(bs2);
+
+    bs1 = psBitSetAlloc(24);
+    bs2 = psBitSetAlloc(24);
+
+    outbs = psBitSetAlloc(40);
+    psBitSet* outbs2 = psBitSetOp(outbs, bs1, "XOR", bs2);
+    if (outbs2 == NULL) {
+        psAbort(__func__,"psBitSetOp failed when input size and output size differed (a recoverable error).");
+    }
+    if (outbs2 != outbs) {
+        psAbort(__func__,"psBitSetOp didn't reuse the given output struct.");
+    }
+    if (outbs2->n != bs1->n) {
+        psAbort(__func__,"psBitSetOp did properly adjust the output psBitSet size.");
+    }
+
+    psErrorClear();
+    psLogMsg(__func__,PS_LOG_INFO,"Following is an error.");
+    outbs = psBitSetOp(outbs, bs1, "FOO", bs2);
+    if (outbs != NULL) {
+        psAbort(__func__,"psBitSetOp returned something in case of a bogus operation.");
+    }
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psErrorStackPrint(stderr,"Error Stack:");
+        psAbort(__func__,"psBitSetOp didn't generate expected error with bogus operator.");
+    }
+    psFree(err);
+
+
+    // try again, though give a valid output bitset -- should free the out upon error to avoid leak.
+    outbs = psBitSetAlloc(24);
+    psErrorClear();
+    psLogMsg(__func__,PS_LOG_INFO,"Following is an error.");
+    outbs = psBitSetOp(outbs, bs1, "FOO", bs2);
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psErrorStackPrint(stderr,"Error Stack:");
+        psAbort(__func__,"psBitSetOp didn't generate expected error with bogus operator.");
+    }
+    psFree(err);
+
+
+    psFree(bs1);
+    psFree(bs2);
+    psFree(outbs);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/collections/tst_psHash00.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psHash00.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psHash00.c	(revision 2163)
@@ -0,0 +1,64 @@
+/*****************************************************************************
+    This code will test whether a hash table can be allocated successfully,
+    then deallocated successfully.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psHash.h"
+#define NUM_HASH_TABLE_BUCKETS 10
+int main()
+{
+    psHash *myHashTable = NULL;
+    int testStatus      = true;
+    int i               = 0;
+    int currentId = psMemGetId();
+    int memLeaks        = 0;
+    printPositiveTestHeader(stdout,
+                            "psHash functions",
+                            "psHashAlloc()");
+
+    myHashTable = psHashAlloc(NUM_HASH_TABLE_BUCKETS);
+
+    if (myHashTable == NULL) {
+        fprintf(stderr, "%s: could not allocate a hash table.", __func__);
+        testStatus = false;
+    }
+
+    if (myHashTable->nbucket != NUM_HASH_TABLE_BUCKETS) {
+        fprintf(stderr, "%s: myHashTable->nbucket not set properly.\n",
+                __func__);
+        testStatus = false;
+
+    }
+
+    if (myHashTable->buckets == NULL) {
+        fprintf(stderr, "%s: myHashTable->buckets is NULL.\n",
+                __func__);
+        testStatus = false;
+
+    }
+
+    for (i=0;i<NUM_HASH_TABLE_BUCKETS;i++) {
+        if (myHashTable->buckets[i] != NULL) {
+            fprintf(stderr, "%s: hash table bucket[%d] not equal to NULL.\n",
+                    __func__, i);
+            testStatus = false;
+        }
+    }
+
+    printFooter(stdout,
+                "psHash functions",
+                "psHashAlloc()",
+                testStatus);
+
+    psFree(myHashTable);
+
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/collections/tst_psHash01.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psHash01.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psHash01.c	(revision 2163)
@@ -0,0 +1,79 @@
+/*****************************************************************************
+    This code will test whether a hash table can be de-allocated successfully.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psHash.h"
+#define NUM_HASH_TABLE_BUCKETS 100
+int imGlobal = 0;
+
+typedef struct
+{
+    char *name;
+}
+ID;
+
+static void IdFree(ID *id);
+
+static ID *IdAlloc(const char *name)
+{
+    ID *id = psAlloc(sizeof(ID));
+    p_psMemSetDeallocator(id,(psFreeFcn)IdFree);
+    id->name = psStringCopy(name);
+
+    return id;
+}
+
+static void IdFree(ID *id)
+{
+    imGlobal++;
+    psFree(id->name);
+}
+
+int main()
+{
+    psHash *myHashTable = NULL;
+    int testStatus      = true;
+    int currentId = psMemGetId();
+    ID* id = NULL;
+    int memLeaks        = 0;
+
+    printPositiveTestHeader(stdout,
+                            "psHash functions",
+                            "psHashFree()");
+
+    myHashTable = psHashAlloc(NUM_HASH_TABLE_BUCKETS);
+    id = IdAlloc("IDA");
+    psHashAdd(myHashTable, "ENTRY00", id);
+    psFree(id);
+    id = IdAlloc("IDB");
+    psHashAdd(myHashTable, "ENTRY01", id);
+    psFree(id);
+    id = IdAlloc("IDC");
+    psHashAdd(myHashTable, "ENTRY02", id);
+    psFree(id);
+    id = IdAlloc("IDD");
+    psHashAdd(myHashTable, "ENTRY03", id);
+    psFree(id);
+    psFree(myHashTable);
+
+    if (imGlobal != 4) {
+        fprintf(stderr, "%s: only (%d/4) entries were freed",
+                __func__, imGlobal);
+        testStatus = false;
+    }
+
+    printFooter(stdout,
+                "psHash functions",
+                "psHashFree()",
+                testStatus);
+
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/collections/tst_psHash02.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psHash02.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psHash02.c	(revision 2163)
@@ -0,0 +1,94 @@
+/*****************************************************************************
+    This code will test whether hash tables entries can be inserted correctly,
+    and retrieved correctly.
+ 
+    NOTE: Add code to test whether duplicates are handled correctly (use a
+    small hash table and lots of keys).
+ *****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psHash.h"
+#define NUM_HASH_TABLE_BUCKETS 100
+int imGlobal = 0;
+
+typedef struct
+{
+    char *name;
+}
+ID;
+static void IdFree(ID *id);
+
+static ID *IdAlloc(const char *name)
+{
+    ID *id = psAlloc(sizeof(ID));
+    p_psMemSetDeallocator(id,(psFreeFcn)IdFree);
+    id->name = psStringCopy(name);
+
+    return id;
+}
+
+static void IdFree(ID *id)
+{
+    imGlobal++;
+    psFree(id->name);
+}
+
+int main()
+{
+    psHash *myHashTable = NULL;
+    int testStatus      = true;
+    int i               = 0;
+    ID *id = NULL;
+    char *myKeys[] = {"ENTRY00", "ENTRY01", "ENTRY02", "ENTRY03", NULL
+                     };
+    char *myData[] = {"IDA", "IDB", "IDC", "IDD", NULL
+                     };
+    int currentId = psMemGetId();
+    int memLeaks        = 0;
+
+    printPositiveTestHeader(stdout,
+                            "psHash functions",
+                            "psHashAdd()");
+
+    myHashTable = psHashAlloc(NUM_HASH_TABLE_BUCKETS);
+    i = 0;
+    while (myKeys[i] != NULL) {
+        id = IdAlloc(myData[i]);
+        psHashAdd(myHashTable, myKeys[i], id);
+        psFree(id);
+        i++;
+    }
+
+    i = 0;
+    while (myKeys[i] != NULL) {
+        id = psHashLookup(myHashTable, myKeys[i]);
+        if (0 != strcmp(myData[i], id->name)) {
+            fprintf(stderr, "%s: Hash table entry for key %s was %s (should be %s).\n",
+                    __func__, myKeys[i], id->name, myData[i]);
+        }
+        i++;
+    }
+    id = psHashLookup(myHashTable, "BogusKey");
+    if (id != NULL) {
+        fprintf(stderr, "%s: Hash table entry for key %s was not NULL.\n",
+                __func__, "BogusKey");
+    }
+
+    //    psHashFree(myHashTable, NULL);
+    psFree(myHashTable);
+
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    printFooter(stdout,
+                "psHash functions",
+                "psHashAdd()",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/collections/tst_psHash03.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psHash03.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psHash03.c	(revision 2163)
@@ -0,0 +1,139 @@
+/*****************************************************************************
+    This code will test whether hash tables entries can be removed correctly.
+ 
+    NOTE: Add code to test whether duplicates are handled correctly.
+ *****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psHash.h"
+#include "psMemory.h"
+#define NUM_HASH_TABLE_BUCKETS 100
+int imGlobal = 0;
+int currentId = 0;
+
+typedef struct
+{
+    char *name;
+}
+ID;
+static void IdFree(ID *id);
+
+// NOTE: This is my own little routine I used in debugging a memory
+// leak.  I will take this out of this file later.
+void printMemBlocks(char *myString)
+{
+    psMemBlock **memBlocks = NULL;
+    psMemBlock *tmp = NULL;
+    int numBlocks = 0;
+
+    numBlocks = psMemCheckLeaks(currentId, &memBlocks, NULL);
+    printf("******************** %s ********************\n", myString);
+    printf("%d mem blocks\n", psMemCheckLeaks(currentId,NULL,stderr));
+    printf("%d blocks\n", numBlocks);
+    printf("*  ");
+    if (memBlocks != NULL) {
+        for (tmp = *memBlocks; tmp != NULL; tmp = tmp->nextBlock) {
+            printf("%d ", (int) tmp->id);
+        }
+    }
+    printf("*\n");
+    printf("*************************************************\n");
+    psFree(memBlocks);
+}
+
+static ID *IdAlloc(const char *name)
+{
+    ID *id = NULL;
+
+    id = psAlloc(sizeof(ID));
+    p_psMemSetDeallocator(id,(psFreeFcn)IdFree);
+
+    id->name = psStringCopy(name);
+
+    return id;
+}
+
+static void IdFree(ID *id)
+{
+    imGlobal++;
+    psFree(id->name);
+}
+
+int main()
+{
+    psHash *myHashTable = NULL;
+    int testStatus      = true;
+    int i               = 0;
+    int TotalKeys       = 0;
+    bool retVal         = false;
+    ID *id = NULL;
+    ID *ids[4];
+    char *myKeys[] = {"ENTRY00", "ENTRY01", "ENTRY02", "ENTRY03", NULL
+                     };
+    char *myData[] = {"IDA", "IDB", "IDC", "IDD", NULL
+                     };
+    int memLeaks        = 0;
+
+    currentId = psMemGetId();
+
+    printPositiveTestHeader(stdout,
+                            "psHash functions",
+                            "psHashRemove()");
+
+    myHashTable = psHashAlloc(NUM_HASH_TABLE_BUCKETS);
+
+    i = 0;
+    while (myKeys[i] != NULL) {
+        ids[i] = IdAlloc(myData[i]);
+        psHashAdd(myHashTable, myKeys[i], ids[i]);
+        i++;
+    }
+    TotalKeys = i - 1;
+
+    i = TotalKeys;
+    while (i >= 0) {
+
+        id = psHashLookup(myHashTable, myKeys[i]);
+        if (0 != strcmp(myData[i], id->name)) {
+            fprintf(stderr, "%s: Hash table entry for key %s was %s (should be %s).\n",
+                    __func__, myKeys[i], id->name, myData[i]);
+        }
+        i--;
+    }
+
+    i = 0;
+    while (myKeys[i] != NULL) {
+        // The psHashRemove() procedure removes the entry from the hash
+        // table and deletes the data.
+        retVal = psHashRemove(myHashTable, myKeys[i]);
+        if (!retVal) {
+            fprintf(stderr,"%s: Hash table entry not removed.\n",__func__);
+        }
+        id = psHashLookup(myHashTable, myKeys[i]);
+        if (id != NULL) {
+            fprintf(stderr, "%s: Hash table entry for key %s not removed.\n",
+                    __func__, "IDA");
+        }
+        i++;
+    }
+
+    printFooter(stdout,
+                "psHash functions",
+                "psHashRemove()",
+                testStatus);
+
+    psFree(myHashTable);
+    for(i=0; i<(TotalKeys+1); i++) {
+        psFree(ids[i]);
+    }
+    memLeaks = psMemCheckLeaks(currentId,NULL,stdout);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(true);
+
+    return (!testStatus);
+}
+
Index: /branches/rel3/psLib/test/collections/tst_psHash04.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psHash04.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psHash04.c	(revision 2163)
@@ -0,0 +1,84 @@
+/*****************************************************************************
+    This code will test whether the call psHashKeyList() function works.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psHash.h"
+#define NUM_HASH_TABLE_BUCKETS 100
+int imGlobal = 0;
+
+typedef struct
+{
+    char *name;
+}
+ID;
+static void IdFree(ID *id);
+
+static ID *IdAlloc(const char *name)
+{
+    ID *id = psAlloc(sizeof(ID));
+    p_psMemSetDeallocator(id,(psFreeFcn)IdFree);
+
+    id->name = psStringCopy(name);
+
+    return id;
+}
+
+static void IdFree(ID *id)
+{
+    imGlobal++;
+    psFree(id->name);
+}
+
+int main()
+{
+    psHash *myHashTable = NULL;
+    int testStatus      = true;
+    int i               = 0;
+    char *myKeys[] = {"ENTRY00", "ENTRY01", "ENTRY02", "ENTRY03", NULL
+                     };
+    char *myData[] = {"IDA", "IDB", "IDC", "IDD", NULL
+                     };
+    int currentId = psMemGetId();
+    int memLeaks        = 0;
+    psList *myLinkList = NULL;
+    psListElem *tmp = NULL;
+    ID* id = NULL;
+
+    printPositiveTestHeader(stdout,
+                            "psHash functions",
+                            "psHashKeyList()");
+
+    myHashTable = psHashAlloc(NUM_HASH_TABLE_BUCKETS);
+    i = 0;
+    while (myKeys[i] != NULL) {
+        id = IdAlloc(myData[i]);
+        psHashAdd(myHashTable, myKeys[i], id);
+        psFree(id);
+        i++;
+    }
+    myLinkList = psHashKeyList(myHashTable);
+    tmp = myLinkList->head;
+    while (tmp != NULL) {
+        printf("Linked List Entries: %s\n", (char *) tmp->data);
+        tmp = tmp->next;
+    }
+
+    psFree(myLinkList);
+
+    printFooter(stdout,
+                "psHash functions",
+                "psHashKeyList()",
+                testStatus);
+
+    psFree(myHashTable);
+
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    return(!testStatus);
+}
Index: /branches/rel3/psLib/test/collections/tst_psList.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psList.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psList.c	(revision 2163)
@@ -0,0 +1,1136 @@
+/** @file  tst_psList.c
+ *
+ *  @brief Contains the tests for psList.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-09 02:24:59 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "psTest.h"
+#include "pslib.h"
+
+void printListInt(psList* list);
+
+
+static int testListAlloc(void);
+static int testListAdd(void);
+static int testListGet(void);
+static int testListRemove(void);
+static int testListConvert(void);
+static int testListIterator(void);
+static int testListFree(void);
+static int testListSort(void);
+
+testDescription tests[] = {
+                              {testListAlloc,487,"psListAlloc",0,false},
+                              {testListAdd,488,"psListAdd",0,false},
+                              {testListGet,489,"psListGet",0,false},
+                              {testListRemove,490,"psListRemove",0,false},
+                              {testListConvert,491,"psListConvert",0,false},
+                              {testListIterator,494,"psListIterator",0,false},
+                              {testListFree,627,"psListFree",0,false},
+                              {testListSort,624,"psListSort",0,false},
+                              {NULL}
+                          };
+
+int main(int argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    if (! runTestSuite(stderr,"psList",tests,argc,argv) ) {
+        psError(__FILE__,"One or more tests failed");
+        return 1;
+    }
+    return 0;
+}
+
+int testListAlloc(void)
+{
+    psList* list;
+    int ref;
+    float* data;
+
+    psLogMsg(__func__,PS_LOG_INFO,"psListAlloc shall create a psList with either 0 or 1 element.");
+
+    data = psAlloc(sizeof(float));
+
+    // if psListAlloc is invoked with a NULL parameter, it shall return an
+    // empty psList struct with head=tail=NULL and n=0. Otherwise, it shall
+    // return a psList of one element (head=tail=data, n=1).
+
+    list = psListAlloc(NULL);
+    if (list == NULL) {
+        psError(__func__,"psListAlloc failed to return a list.");
+        return 1;
+    }
+
+    if (list->head != NULL || list->tail != NULL) {
+        psError(__func__,"head and/or tail was not NULL for empty list.");
+        return 2;
+    }
+
+    if (list->size != 0) {
+        psError(__func__,"size of list wasn't zero for empty list.");
+        return 3;
+    }
+
+    psFree(list);
+
+    list = psListAlloc(data);
+    if (list == NULL) {
+        psError(__func__,"psListAlloc failed to return a list.");
+        return 4;
+    }
+
+    if (list->head == NULL || list->tail == NULL) {
+        psError(__func__,"head and/or tail was NULL for one-element new list.");
+        return 5;
+    }
+
+    if (list->head->data != data || list->tail->data != data) {
+        psError(__func__,"head and/or tail didn't point to data's node for one-element new list.");
+        return 6;
+    }
+
+    if (list->size != 1) {
+        psError(__func__,"size of list wasn't correctly set for new, one-element list.");
+        return 7;
+    }
+
+    ref = psMemGetRefCounter(data);
+    if (ref != 2) {
+        psError(__func__,"psList didn't increment reference count of data (%d.",ref);
+        return 8;
+    }
+
+
+    psFree(list);
+
+    psFree(data);
+
+    return 0;
+}
+
+int testListAdd(void)
+{
+    psList* list = NULL;
+    int* data = NULL;
+
+    psLogMsg(__func__,PS_LOG_INFO,"psListAdd shall add an element to list");
+
+    /*
+        psListAdd(list,data,where) should be tested in the instance where:
+
+        1. list is NULL (error)
+        2. data is NULL (error, list should not grow)
+        3. where is PS_LIST_HEAD or PS_LIST_TAIL
+        4. where is not PS_LIST_* but <0
+        5. where is >0
+    */
+
+    data = psAlloc(sizeof(int));
+    *data = 1;
+
+    //  1. list is NULL (error)
+    if (psListAdd(NULL,PS_LIST_HEAD,data)) {
+        psError(__func__,"psListAdd was given a NULL list, but returned a true/success.");
+        return 1;
+    }
+
+    list = psListAlloc(data);
+    psFree(data);
+    if (list->size != 1) {
+        psError(__func__,"psListAlloc didn't create a list properly.");
+        return 2;
+    }
+
+    //  2. data is NULL (error, list should not grow)
+    if (psListAdd(list, PS_LIST_HEAD,NULL)) {
+        psError(__func__,"psListAdd successfully added a NULL data item?");
+        return 40;
+    }
+    if ( list->size != 1) {
+        psError(__func__,"psListAdd with a NULL data element changed the list size or returned success.");
+        return 3;
+    }
+
+    //  3. where is PS_LIST_HEAD or PS_LIST_TAIL
+    data = psAlloc(sizeof(int));
+    *data = 2;
+    if ( ! psListAdd(list,PS_LIST_HEAD,data) ) {
+        psError(__func__,"psListAdd failed to add a data item to head.");
+        return 21;
+    }
+
+    if (psMemGetRefCounter(data) != 2) {
+        psError(__func__,"psListAdd didn't increment the data reference count.");
+        return 20;
+    }
+    psFree(data);
+
+    // verify that the size incremented
+    if (list->size != 2) {
+        psError(__func__,"psListAdd didn't increment the size by one");
+        return 4;
+    }
+
+    // verify that the head is the inserted data item
+    if (*(int*)list->head->data != 2) {
+        psError(__func__,"psListAdd with PS_LIST_HEAD didn't insert at the head.");
+        return 5;
+    }
+
+    data = psAlloc(sizeof(int));
+    *data = 3;
+    if ( ! psListAdd(list,PS_LIST_TAIL,data) ) {
+        psError(__func__,"psListAdd failed to add a data item to tail.");
+        return 21;
+    }
+
+    if (psMemGetRefCounter(data) != 2) {
+        psError(__func__,"psListAdd didn't increment the data reference count.");
+        return 22;
+    }
+    psFree(data);
+    // verify that the size incremented
+    if (list->size != 3) {
+        psError(__func__,"psListAdd didn't increment the size by 1");
+        return 6;
+    }
+
+    // verify that the head is still the same
+    if (*(int*)list->head->data != 2) {
+        psError(__func__,"psListAdd with PS_LIST_TAIL modified the head.");
+        return 7;
+    }
+
+    // verify that the tail is the data item inserted
+    if (*(int*)list->tail->data != 3) {
+        psError(__func__,"psListAdd with PS_LIST_TAIL didn't insert at the tail.");
+        return 8;
+    }
+
+    // 4. where is not PS_LIST_* but <0
+
+    data = psAlloc(sizeof(int));
+    *data = 4;
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error with invalid insert location");
+
+    if ( psListAdd(list,-10,data) ) {
+        psError(__func__,"psListAdd successfully added data to a -10 position?");
+        return 30;
+    }
+    if (psMemGetRefCounter(data) != 1) {
+        psError(__func__,"psListAdd incremented the data reference count.");
+        return 24;
+    }
+    psFree(data);
+    // verify that the size wasn't incremented
+    if (list->size != 3) {
+        printListInt(list);
+        psError(__func__,"psListAdd didn't insert to head when where was invalid.");
+        return 9;
+    }
+
+    // 5. where is >0
+    data = psAlloc(sizeof(int));
+    *data = 5;
+
+    if ( ! psListAdd(list,1,data) ) {
+        psError(__func__,"psListAdd failed to add data to 1 position.");
+        return 30;
+    }
+
+    if (psMemGetRefCounter(data) != 2) {
+        psError(__func__,"psListAdd didn't increment the data reference count.");
+        return 25;
+    }
+    psFree(data);
+    // verify that the size incremented
+    if (list->size != 4 || *(int*)list->head->next->data != 5) {
+        printListInt(list);
+        psError(__func__,"psListAdd didn't insert to position #1.");
+        return 10;
+    }
+
+    data = psAlloc(sizeof(int));
+    *data = 6;
+    if ( ! psListAdd(list,3,data) ) {
+        psError(__func__,"psListAdd failed to add data to 4 position.");
+        return 31;
+    }
+    if (psMemGetRefCounter(data) != 2) {
+        psError(__func__,"psListAdd didn't increment the data reference count.");
+        return 26;
+    }
+    psFree(data);
+    // verify that the size incremented
+    if (list->size != 5  || *(int *)list->head->next->next->next->data != 6) {
+        printListInt(list);
+        psError(__func__,"psListAdd didn't insert to position #4.");
+        return 50;
+    }
+
+    data = psAlloc(sizeof(int));
+    *data = 7;
+    if ( ! psListAdd(list,2,data) ) {
+        psError(__func__,"psListAdd failed to add data to 2 position.");
+        return 32;
+    }
+    if (psMemGetRefCounter(data) != 2) {
+        psError(__func__,"psListAdd didn't increment the data reference count.");
+        return 28;
+    }
+    psFree(data);
+    // verify that the size incremented
+    if (list->size != 6  || *(int *)list->head->next->next->data != 7) {
+        printListInt(list);
+        psError(__func__,"psListAdd didn't insert to position #2.");
+        return 11;
+    }
+
+    data = psAlloc(sizeof(int));
+    *data = 7;
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be a warning.");
+
+    if ( ! psListAdd(list,9,data) ) {
+        psError(__func__,"psListAdd failed to add data to a 9 position?");
+        return 30;
+    }
+
+    if (psMemGetRefCounter(data) != 2) {
+        psError(__func__,"psListAdd didn't increment the data reference count.");
+        return 29;
+    }
+
+    psFree(data);
+
+    // verify that the size incremented
+    if (list->size != 7) {
+        printListInt(list);
+        psError(__func__,"psListAdd didn't insert to position #9.");
+        return 12;
+    }
+
+    psFree(list);
+
+    return 0;
+}
+
+void printListInt(psList* list)
+{
+    int* data = NULL;
+    bool first = true;
+
+    psListSetIterator(list,PS_LIST_HEAD);
+    data = psListGetCurrent(list);
+
+    while ( data != NULL ) {
+        if (!first) {
+            printf(", %d",*(int*)data);
+        } else {
+            printf("%d",*(int*)data);
+            first = false;
+        }
+        data = psListGetNext(list);
+    }
+
+    printf(".\n");
+}
+
+
+int testListGet(void)
+{
+    psList* list = NULL;
+    int* data;
+
+    /*
+     psListGet(list,which) shall be tested with the following instances
+
+        1. list is NULL.
+        2. which>0 and which<list.n.
+        3. which>list.n.
+        4. which=PS_LIST_HEAD
+        5. which=PS_LIST_NEXT
+        6. which=PS_LIST_TAIL
+        7. which=PS_LIST_PREV
+        8. which<0 and not any PS_LIST_* values
+    */
+
+    //  1. list is NULL.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error");
+    if (psListGet(list,PS_LIST_HEAD) != NULL) {
+        psError(__func__,"psListGet didn't return NULL given a NULL list.");
+        return 1;
+    };
+
+    // create a list
+    data = psAlloc(sizeof(int));
+    *data = 0;
+    list = psListAlloc(data);
+    psFree(data);
+
+    data = psAlloc(sizeof(int));
+    *data = 1;
+    psListAdd(list,PS_LIST_TAIL,data);
+    psFree(data);
+
+    data = psAlloc(sizeof(int));
+    *data = 2;
+    psListAdd(list,PS_LIST_TAIL,data);
+    psFree(data);
+
+    data = psAlloc(sizeof(int));
+    *data = 3;
+    psListAdd(list,PS_LIST_TAIL,data);
+    psFree(data);
+
+    //  2. which>0 and which<list.n.
+    data = (int*)psListGet(list,3);
+    if (data == NULL || *data != 3) {
+        psError(__func__,"psListGet failed with which=3");
+        return 2;
+    }
+    data = (int*)psListGet(list,1);
+    if (data == NULL || *data != 1) {
+        psError(__func__,"psListGet failed with which=1");
+        return 3;
+    }
+
+    //  3. which>=list.n.
+    data = (int*)psListGet(list,5);
+    if (data != NULL) {
+        psError(__func__,"psListGet failed with which=5");
+        return 4;
+    }
+    data = (int*)psListGet(list,4);
+    if (data != NULL) {
+        psError(__func__,"psListGet failed with which=4");
+        return 5;
+    }
+
+    //  4. which=PS_LIST_HEAD
+    data = (int*)psListGet(list,PS_LIST_HEAD);
+    if (data == NULL || *data != 0) {
+        psError(__func__,"psListGet failed with which=PS_LIST_HEAD");
+        return 6;
+    }
+
+    //  5. which=PS_LIST_NEXT
+    data = (int*)psListGet(list,PS_LIST_NEXT);
+    if (data == NULL || *data != 1) {
+        psError(__func__,"psListGet failed with which=PS_LIST_NEXT");
+        return 7;
+    }
+
+    //  6. which=PS_LIST_TAIL
+    data = (int*)psListGet(list,PS_LIST_TAIL);
+    if (data == NULL || *data != 3) {
+        psError(__func__,"psListGet failed with which=PS_LIST_TAIL");
+        return 8;
+    }
+
+    //  7. which=PS_LIST_PREV
+    data = (int*)psListGet(list,PS_LIST_PREVIOUS);
+    if (data == NULL || *data != 2) {
+        psError(__func__,"psListGet failed with which=PS_LIST_PREV");
+        return 9;
+    }
+
+    psFree(list);
+
+    return 0;
+}
+
+int testListRemove(void)
+{
+    psList* list = NULL;
+    int* data;
+
+    /*
+        psListRemove(list,data,which) should be tested under the following conditions:
+
+        1. list is NULL
+        2. which is PS_LIST_HEAD (remove first element of list)
+        3. which is PS_LIST_TAIL (remove last element of list)
+        4. which is PS_LIST_NEXT (element right of cursor [which should be head,tail, and neither])
+        5. which is PS_LIST_PREV (element left of cursor [which should be head,tail, and neither])
+        6. which is PS_LIST_UNKNOWN and data=NULL (error)
+        7. which is PS_LIST_UNKNOWN and data=[head,tail,other list items]
+        8. which is PS_LIST_UNKNOWN and data!=NULL and data!=any element in list
+
+        In all conditions that are not an error, list.n shall be decremented and only the specified element
+        shall be removed. After each step, list.n should be checked to verify that it is the true
+        number of elements in list.
+    */
+
+    //  1. list is NULL.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error");
+    if (psListRemove(list,PS_LIST_HEAD,NULL)) {
+        psError(__func__,"psListRemove didn't return false given a NULL list.");
+        return 1;
+    };
+
+    // create a list
+    list = psListAlloc(NULL);
+
+    for (int lcv=0;lcv<15;lcv++) {
+        data = psAlloc(sizeof(int));
+        *data = lcv;
+        psListAdd(list,PS_LIST_TAIL,data);
+        psMemDecrRefCounter(data);
+    }
+
+
+    // 2. which is PS_LIST_HEAD (remove first element of list)
+    data = psListGet(list,PS_LIST_HEAD);
+    if ( (! psListRemove(list,PS_LIST_HEAD,NULL)) ||
+            (psListGet(list,PS_LIST_HEAD) == data) ) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_HEAD");
+        return 1;
+    }
+
+    if (list->size != 14) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 14.");
+        return 1;
+    }
+
+    // 3. which is PS_LIST_TAIL (remove last element of list)
+    data = psListGet(list,PS_LIST_TAIL);
+    if ( (! psListRemove(list,PS_LIST_TAIL,NULL)) ||
+            (psListGet(list,PS_LIST_TAIL) == data) ) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_TAIL");
+        return 1;
+    }
+
+    if (list->size != 13) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 13.");
+        return 1;
+    }
+
+    // 4. which is PS_LIST_NEXT (element right of cursor [which should be head,tail, and neither])
+    psListSetIterator(list,PS_LIST_HEAD);
+    if (! psListRemove(list,PS_LIST_NEXT,NULL)) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_NEXT @ PS_LIST_HEAD");
+        return 1;
+    }
+
+    if (list->size != 12) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 12.");
+        return 1;
+    }
+
+    psListSetIterator(list,PS_LIST_TAIL);
+    psLogMsg(__func__,PS_LOG_INFO,"Next message should be an error");
+    if (psListRemove(list,PS_LIST_NEXT,NULL)) {
+        printListInt(list);
+        psError(__func__,"Removed something with PS_LIST_NEXT @ PS_LIST_TAIL");
+        return 1;
+    }
+
+    data = psListGet(list,3);
+    psListSetIterator(list,2);
+    if ( (!psListRemove(list,PS_LIST_NEXT,NULL)) ||
+            ( psListGet(list,3) == data) ) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_NEXT @ which=2");
+        return 1;
+    }
+
+    if (list->size != 11) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 11.");
+        return 1;
+    }
+
+    // 5. which is PS_LIST_PREV (element left of cursor [which should be head,tail, and neither])
+    psListSetIterator(list,PS_LIST_HEAD);
+    psLogMsg(__func__,PS_LOG_INFO,"Next message should be an error");
+    if (psListRemove(list,PS_LIST_PREVIOUS,NULL)) {
+        printListInt(list);
+        psError(__func__,"removed something for PS_LIST_PREVIOUS @ PS_LIST_HEAD");
+        return 1;
+    }
+
+    data = psListGet(list,9);
+    psListSetIterator(list,PS_LIST_TAIL);
+    if ( (!psListRemove(list,PS_LIST_PREVIOUS,NULL)) ||
+            (psListGet(list,9) == data) ) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_PREVIOUS @ PS_LIST_TAIL");
+        return 1;
+    }
+
+    if (list->size != 10) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 10.");
+        return 1;
+    }
+
+    data = psListGet(list,1);
+    psListSetIterator(list,2);
+    if ( (!psListRemove(list,PS_LIST_PREVIOUS,NULL)) ||
+            ( psListGet(list,1) == data) ) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_PREVIOUS @ which=2");
+        return 1;
+    }
+
+    if (list->size != 9) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 9.");
+        return 1;
+    }
+
+    // 6. which is PS_LIST_UNKNOWN and data=NULL (error)
+    psLogMsg(__func__,PS_LOG_INFO,"Next message should be an error");
+    if (psListRemove(list,PS_LIST_UNKNOWN,NULL)) {
+        printListInt(list);
+        psError(__func__,"removed something for PS_LIST_UNKNOWN with data=NULL");
+        return 1;
+    }
+
+    // 7. which is PS_LIST_UNKNOWN and data=[head,tail,other list items]
+    data = psListGet(list,PS_LIST_HEAD);
+    if ( (! psListRemove(list,PS_LIST_UNKNOWN,data)) ||
+            (psListGet(list,PS_LIST_HEAD) == data) ) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_UNKNOWN @ PS_LIST_HEAD");
+        return 1;
+    }
+
+    if (list->size != 8) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 8.");
+        return 1;
+    }
+
+    data = psListGet(list,PS_LIST_TAIL);
+    if ( (!psListRemove(list,PS_LIST_UNKNOWN,data)) ||
+            (psListGet(list,PS_LIST_TAIL) == data) ) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_UNKNOWN @ PS_LIST_TAIL");
+        return 1;
+    }
+
+    if (list->size != 7) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 7.");
+        return 1;
+    }
+
+    psListSetIterator(list,PS_LIST_HEAD);
+
+    data = psListGet(list,PS_LIST_NEXT);
+    if ( (! psListRemove(list,PS_LIST_UNKNOWN,data))||
+            (psListGet(list,1) == data) ) {
+        printListInt(list);
+        psError(__func__,"Failed to remove PS_LIST_UNKNOWN @ which=1");
+        return 1;
+    }
+
+    if (list->size != 6) {
+        printListInt(list);
+        psError(__func__,"Didn't decrement size properly to 6.");
+        return 1;
+    }
+
+    // 8. which is PS_LIST_UNKNOWN and data!=NULL and data!=any element in list
+    psLogMsg(__func__,PS_LOG_INFO,"Next message should be an error");
+    if ( psListRemove(list,PS_LIST_UNKNOWN,data) ) {
+        printListInt(list);
+        psError(__func__,"removed something for PS_LIST_UNKNOWN with previously removed item");
+        return 1;
+    }
+
+    // clear out the list
+    psListRemove(list,PS_LIST_HEAD,NULL);
+    psListRemove(list,PS_LIST_HEAD,NULL);
+    psListRemove(list,PS_LIST_HEAD,NULL);
+    psListRemove(list,PS_LIST_HEAD,NULL);
+    psListRemove(list,PS_LIST_HEAD,NULL);
+
+    data = psListGet(list,PS_LIST_HEAD);
+    if ( (! psListRemove(list,PS_LIST_HEAD,data)) ||
+            (psListGet(list,PS_LIST_HEAD) == data) ) {
+        printListInt(list);
+        psError(__func__,"Failed to remove last element");
+        return 1;
+    }
+
+    if (list->size != 0) {
+        printListInt(list);
+        psError(__func__,"Didn't remove all the elements.");
+        return 1;
+    }
+
+    psFree(list);
+
+    return 0;
+
+}
+
+int testListConvert(void)
+{
+
+    psList* list = NULL;
+    psArray* arr = NULL;
+    int* data;
+
+    /*
+        array=psListToArray(list) shall take each element of the list, increment
+        their reference, and insert them into the returned fresh void* array.
+        The list shall not be changed, except for the element reference increment.
+    */
+
+    // test dlist -> array
+
+    // create a list
+    list = psListAlloc(NULL);
+    for (int lcv=0;lcv<15;lcv++) {
+        data = psAlloc(sizeof(int));
+        *data = lcv;
+        psListAdd(list,PS_LIST_TAIL,data);
+        psMemDecrRefCounter(data);
+    }
+
+    arr = psListToArray(list);
+
+    if (arr->n != 15 || list->size != 15) {
+        psError(__func__,"The created array didn't have the proper size");
+        return 1;
+    }
+    for (int i=0;i<arr->n;i++) {
+        if (i != *(int*)arr->data[i]) {
+            psError(__func__,"Element %d of array is incorrect (%d).",
+                    i,*(int*)arr->data[i]);
+            return 1;
+        }
+        if (i != *(int*)psListGet(list,i)) {
+            psError(__func__,"Element %d of list is incorrect (%d).",
+                    i,*(int*)arr->data[i]);
+            return 1;
+        }
+        if (psMemGetRefCounter(arr->data[i]) != 2) {
+            psError(__func__,"Element %d had wrong reference count (%d).",
+                    i,psMemGetRefCounter(arr->data[i]));
+            return 1;
+        }
+    }
+
+    psFree(arr);
+    psFree(list);
+
+    // test array -> dlist
+
+    // create an array
+    arr = psArrayAlloc(15);
+    arr->n = arr->nalloc;
+    for (int lcv=0;lcv<15;lcv++) {
+        data = psAlloc(sizeof(int));
+        *data = lcv;
+        arr->data[lcv] = data;
+    }
+
+    list = psArrayToList(arr);
+
+    if (arr->n != 15 || list->size != 15) {
+        psError(__func__,"The created array didn't have the proper size");
+        return 1;
+    }
+    for (int i=0;i<arr->n;i++) {
+        if (i != *(int*)arr->data[i]) {
+            psError(__func__,"Element %d of array is incorrect (%d).",
+                    i,*(int*)arr->data[i]);
+            return 1;
+        }
+        if (i != *(int*)psListGet(list,i)) {
+            psError(__func__,"Element %d of list is incorrect (%d).",
+                    i,*(int*)arr->data[i]);
+            return 1;
+        }
+        if (psMemGetRefCounter(arr->data[i]) != 2) {
+            psError(__func__,"Element %d had wrong reference count (%d).",
+                    i,psMemGetRefCounter(arr->data[i]));
+            return 1;
+        }
+    }
+
+    psFree(arr);
+    psFree(list);
+
+    // now, make sure if input array/list is NULL, output is NULL
+
+    arr = psListToArray(NULL);
+    if (arr != NULL) {
+        psError(__func__,"psListToArray didn't return NULL when given NULL");
+        return 1;
+    }
+
+    list = psArrayToList(NULL);
+    if (list != NULL) {
+        psError(__func__,"psArrayToList didn't return NULL when given NULL");
+        return 1;
+    }
+
+    // now, see what happens with a zero-size array/list
+    arr = psArrayAlloc(1);
+    arr->n = 0;
+    list = psArrayToList(arr);
+    if (list == NULL) {
+        psError(__func__,"psArrayToList didn't create an empty list from an "
+                "empty array.");
+        return 1;
+    }
+    psFree(arr);
+    psFree(list);
+
+    list = psListAlloc(NULL);
+    arr = psListToArray(list);
+    if (arr == NULL) {
+        psError(__func__,"psArrayToList didn't create an empty array from an "
+                "empty list.");
+        return 1;
+    }
+    psFree(arr);
+    psFree(list);
+
+    return 0;
+}
+
+int testListIterator(void)
+{
+    psList* list = NULL;
+    int* data;
+
+    psLogMsg(__func__,PS_LOG_INFO," psListSetIterator/psListGetNext/psListGetPrev"
+             " shall move the list cursor to the specified location");
+
+    /*
+            psDlistSetIterator(list,where) shall:
+
+            1. output error message and do nothing if list=NULL
+            2. set list.cursor to list.head if where=PS_LIST_HEAD
+            3. set list.cursor to list.tail if where=PS_LIST_TAIL
+            4. set list.cursor to list.cursor->next if where=PS_LIST_NEXT
+            5. set list.cursor to list.cursor->prev if where=PS_LIST_PREV
+            6. leave list.cursor untouched if where=PS_LIST_UNKNOWN or PS_LIST_CURRENT
+
+            psDlistGetNext(list) shall be functionally equivalent to
+            psDlistSetIterator(list,PS_LIST_NEXT) but returns list.cursor.
+
+            psDlistGetPrev(list) shall be functionally equivalent to
+            psDlistSetIterator(list,PS_LIST_PREV) but returns list.cursor.
+    */
+
+    // create a list
+    list = psListAlloc(NULL);
+    for (int lcv=0;lcv<15;lcv++) {
+        data = psAlloc(sizeof(int));
+        *data = lcv;
+        psListAdd(list,PS_LIST_TAIL,data);
+        psFree(data);
+    }
+
+
+    // 1. output error message and do nothing if list=NULL
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error with "
+             "'Unexpected null pointer'");
+    psListSetIterator(NULL,PS_LIST_HEAD);
+
+    // 3. set list.cursor to list.tail if where=PS_LIST_TAIL
+    psListSetIterator(list,PS_LIST_TAIL);
+    if (*(int*)psListGetCurrent(list) != 14) {
+        psError(__func__,"Didn't successfully move cursor to tail.");
+        return 1;
+    }
+
+    // 2. set list.cursor to list.head if where=PS_LIST_HEAD
+    psListSetIterator(list,PS_LIST_HEAD);
+    if (*(int*)psListGetCurrent(list) != 0) {
+        psError(__func__,"Didn't successfully move cursor to head.");
+        return 2;
+    }
+
+    // 4. set list.cursor to list.cursor->next if where=PS_LIST_NEXT
+    psListSetIterator(list,PS_LIST_NEXT);
+    if (*(int*)psListGetCurrent(list) != 1) {
+        psError(__func__,"Didn't successfully move cursor to next.");
+        return 3;
+    }
+    psListSetIterator(list,PS_LIST_NEXT);
+    if (*(int*)psListGetCurrent(list) != 2) {
+        psError(__func__,"Didn't successfully move cursor to next twice.");
+        return 4;
+    }
+
+    // 5. set list.cursor to list.cursor->prev if where=PS_LIST_PREV
+    psListSetIterator(list,PS_LIST_PREVIOUS);
+    if (*(int*)psListGetCurrent(list) != 1) {
+        psError(__func__,"Didn't successfully move cursor to previous.");
+        return 5;
+    }
+    psListSetIterator(list,PS_LIST_PREVIOUS);
+    if (*(int*)psListGetCurrent(list) != 0) {
+        psError(__func__,"Didn't successfully move cursor to previous twice.");
+        return 6;
+    }
+
+    // 6. leave list.cursor untouched if where=PS_LIST_UNKNOWN or PS_LIST_CURRENT
+    psListSetIterator(list,PS_LIST_NEXT);   // move off of head (works according to above)
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error with 'Can't move to an unknown position.'");
+    psListSetIterator(list,PS_LIST_UNKNOWN);
+    if (*(int*)psListGetCurrent(list) != 1) {
+        psError(__func__,"PS_LIST_UNKNOWN moved cursor.");
+        return 7;
+    }
+    psListSetIterator(list,PS_LIST_CURRENT);
+    if (*(int*)psListGetCurrent(list) != 1) {
+        psError(__func__,"PS_LIST_CURRENT moved cursor.");
+        return 8;
+    }
+
+    // test psListGetPrevious/Next
+    if (*(int*)psListGetNext(list) != 2) {
+        psError(__func__,"psListGetNext didn't move cursor to next.");
+        return 9;
+    }
+    if (*(int*)psListGetNext(list) != 3) {
+        psError(__func__,"psListGetNext didn't move cursor to next.");
+        return 10;
+    }
+    if (*(int*)psListGetPrevious(list) != 2) {
+        psError(__func__,"psListGetPrevious didn't move cursor to previous.");
+        return 11;
+    }
+    if (*(int*)psListGetPrevious(list) != 1) {
+        psError(__func__,"psListGetPrevious didn't move cursor to previous.");
+        return 12;
+    }
+    if (*(int*)psListGetPrevious(list) != 0) {
+        psError(__func__,"psListGetPrevious didn't move cursor to previous..");
+        return 13;
+    }
+    if (psListGetPrevious(list) != NULL) {
+        psError(__func__,"psListGetPrevious moved cursor beyond head.");
+        return 14;
+    }
+
+    psListSetIterator(list,PS_LIST_TAIL); // works according to an above test
+    if (psListGetNext(list) != NULL) {
+        psError(__func__,"psListGetNext moved cursor beyond tail.");
+        return 15;
+    }
+
+    psFree(list);
+
+    return 0;
+}
+
+int testListFree(void)
+{
+    float* data[15];
+    psList* list;
+
+    /*
+    Call psDlistAlloc to create a doubly linked list.
+
+    Create several data items and add them to the list.
+
+    Verify the data item's reference counter are incremented after adding to the list.
+    (not really needed, as psListAdd is tested elsewhere)
+    */
+
+    list = psListAlloc(NULL);
+    for (int lcv=0;lcv<15;lcv++) {
+        data[lcv] = psAlloc(sizeof(int));
+        *data[lcv] = lcv;
+        psListAdd(list,PS_LIST_TAIL,data[lcv]);
+        if (psMemGetRefCounter(data[lcv]) != 2) {
+            psError(__func__,"Reference counter for data was not incremented");
+            return 1;
+        }
+    }
+
+    /*
+    Verify items are within the list.
+    (not needed, as psListAdd is tested elsewhere, but check anyway.)
+    */
+    if (list->size != 15) {
+        psError(__func__,"List wasn't populated as expected?");
+        return 2;
+    }
+
+    /*
+    Call psDlistFree with NULL specified as the elemFree function.
+    */
+
+    psFree(list);
+
+    /*
+    Verify the list is deallocated but not the data items.
+    (accomplished by checking for memory leaks)
+
+    Verify the data item's reference counters are decremented by one compared to when added to the list.
+    (technically, this could be accomplished by checking memory leaks too, but I checked anyway)
+    */
+
+    for (int i=0;i<15;i++) {
+        if (psMemGetRefCounter(data[i]) != 1) {
+            psError(__func__,"pslistFree didn't decrement the data item's reference counter");
+            return 3;
+        }
+        psFree(data[i]);
+    }
+
+    return 0;
+}
+
+int testListSort(void)
+{
+    psList* list;
+
+    list = psListAlloc(NULL);
+
+    for (int lcv=0;lcv<15;lcv++) {
+        float* data = psAlloc(sizeof(int));
+        if (lcv < 7) {
+            *data = 13-lcv*2;
+        } else {
+            *data = lcv*2-12;
+        }
+        psListAdd(list,PS_LIST_TAIL,data);
+        psFree(data);
+
+    }
+
+    printf("original list = [");
+    for (float* iter = psListGet(list,PS_LIST_HEAD);
+            iter != NULL;
+            iter = psListGet(list,PS_LIST_NEXT)) {
+        printf(" %.1f",*iter);
+    }
+    printf(" ]\n");
+
+    list = psListSort(list,psCompareF32Ptr);
+
+    printf("sorted list = [");
+    for (float* iter = psListGet(list,PS_LIST_HEAD);
+            iter != NULL;
+            iter = psListGet(list,PS_LIST_NEXT)) {
+        printf(" %.1f",*iter);
+    }
+    printf(" ]\n");
+
+    float* prevValue = psListGet(list,PS_LIST_HEAD);
+    for (float* iter = psListGet(list,PS_LIST_NEXT);
+            iter != NULL;
+            iter = psListGet(list,PS_LIST_NEXT)) {
+        if (*prevValue > *iter) {
+            psError(__func__,"Hey, the list wasn't sorted!?");
+            return 1;
+        }
+    }
+
+    list = psListSort(list,psCompareDescendingF32Ptr);
+
+    printf("descending sort list = [");
+    for (float* iter = psListGet(list,PS_LIST_HEAD);
+            iter != NULL;
+            iter = psListGet(list,PS_LIST_NEXT)) {
+        printf(" %.1f",*iter);
+    }
+    printf(" ]\n");
+
+    prevValue = psListGet(list,PS_LIST_HEAD);
+    for (float* iter = psListGet(list,PS_LIST_NEXT);
+            iter != NULL;
+            iter = psListGet(list,PS_LIST_NEXT)) {
+        if (*prevValue < *iter) {
+            psError(__func__,"Hey, the list wasn't sorted!?");
+            return 1;
+        }
+    }
+
+    psFree(list);
+
+    /********** OK, now do the same thing with ints. *************/
+
+    list = psListAlloc(NULL);
+
+    for (int lcv=0;lcv<15;lcv++) {
+        psU32* data = psAlloc(sizeof(int));
+        if (lcv < 7) {
+            *data = 13-lcv*2;
+        } else {
+            *data = lcv*2-12;
+        }
+        psListAdd(list,PS_LIST_TAIL,data);
+        psFree(data);
+
+    }
+
+    printf("original list = [");
+    for (psU32* iter = psListGet(list,PS_LIST_HEAD);
+            iter != NULL;
+            iter = psListGet(list,PS_LIST_NEXT)) {
+        printf(" %d",*iter);
+    }
+    printf(" ]\n");
+
+    list = psListSort(list,psCompareU32Ptr);
+
+    printf("sorted list = [");
+    for (psU32* iter = psListGet(list,PS_LIST_HEAD);
+            iter != NULL;
+            iter = psListGet(list,PS_LIST_NEXT)) {
+        printf(" %d",*iter);
+    }
+    printf(" ]\n");
+
+    psU32* prev = psListGet(list,PS_LIST_HEAD);
+    for (psU32* iter = psListGet(list,PS_LIST_NEXT);
+            iter != NULL;
+            iter = psListGet(list,PS_LIST_NEXT)) {
+        if (*prev > *iter) {
+            psError(__func__,"Hey, the list wasn't sorted!?");
+            return 1;
+        }
+    }
+
+    list = psListSort(list,psCompareDescendingU32Ptr);
+
+    printf("descending sort list = [");
+    for (psU32* iter = psListGet(list,PS_LIST_HEAD);
+            iter != NULL;
+            iter = psListGet(list,PS_LIST_NEXT)) {
+        printf(" %d",*iter);
+    }
+    printf(" ]\n");
+
+    prev = psListGet(list,PS_LIST_HEAD);
+    for (psU32* iter = psListGet(list,PS_LIST_NEXT);
+            iter != NULL;
+            iter = psListGet(list,PS_LIST_NEXT)) {
+        if (*prev < *iter) {
+            psError(__func__,"Hey, the list wasn't sorted!?");
+            return 1;
+        }
+    }
+
+    psFree(list);
+
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/collections/tst_psMetadataIO.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psMetadataIO.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psMetadataIO.c	(revision 2163)
@@ -0,0 +1,186 @@
+/** @file  tst_psMetadataIO.c
+*
+*  @brief Test driver for psMetadataIO functions
+*
+*  This test driver contains the following tests for psMetadata:
+*    Test A - Read config file with overwrite set true
+*    Test B - Read config file with overwrite set false
+*    Test C - Read config file without auto-allocation of metadata
+*    Test D - Attempt to use null fileName argument
+*    Test E - Attempt to open nonexistant file
+*    Test F - Free psMetadata
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.2 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-10-06 22:51:31 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *metadataItem, char *spaces);
+
+static void printMetadataItemList(psList *metadataItemList)
+{
+    psMetadataItem *entryChild = NULL;
+
+    psListSetIterator(metadataItemList, PS_LIST_HEAD);
+    entryChild = psListGetCurrent(metadataItemList);
+    while (entryChild != NULL) {
+        printMetadataItem(entryChild, "    ");
+        entryChild = psListGetNext(metadataItemList);
+    }
+}
+
+static void printMetadataList(psList *metadataItemList)
+{
+    psMetadataItem *entryChild = NULL;
+
+    psListSetIterator(metadataItemList, PS_LIST_HEAD);
+    entryChild = psListGetCurrent(metadataItemList);
+    while (entryChild != NULL) {
+        printMetadataItem(entryChild, " ");
+        entryChild = psListGetNext(metadataItemList);
+    }
+}
+static void printMetadataItem(psMetadataItem *metadataItem, char *spaces)
+{
+
+    psVector *vec = NULL;
+
+
+    printf("%sKey Name: %8s  ", spaces, metadataItem->name);
+    printf("Key Type: %2d  ", metadataItem->type);
+
+    switch (metadataItem->type ) {
+    case PS_META_ITEM_SET:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_BOOL:
+        printf("Key Value: %15d  ", metadataItem->data.B);
+        break;
+    case PS_META_S32:
+        printf("Key Value: %15d  ", metadataItem->data.S32);
+        break;
+    case PS_META_F32:
+        printf("Key Value: %15.3f  ", metadataItem->data.F32);
+        break;
+    case PS_META_F64:
+        printf("Key Value: %15.3f  ", metadataItem->data.F64);
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    case PS_META_VEC:
+        vec = (psVector*)metadataItem->data.V;
+        printf("Key Value: ");
+        for(int i=0; i<vec->nalloc;i++) {
+            printf("%d ", vec->data.S32[i]);
+        }
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        printf("Value: unknown ");
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+
+    if(metadataItem->items->size) {
+        printMetadataItemList(metadataItem->items);
+    }
+}
+
+static void printMetadataTable(psHash *mdTable)
+{
+    int i;
+    psHashBucket* ptr = NULL;
+    for(i=0; i<mdTable->nbucket; i++) {
+        ptr = mdTable->buckets[i];
+        while (ptr != NULL) {
+            printMetadataItem(ptr->data, " ");
+            ptr = ptr->next;
+        }
+    }
+}
+
+static void printMetadata(psMetadata *metadata)
+{
+    printf("\nContents of metadata list:\n");
+    printMetadataList(metadata->list);
+    printf("\nContents of metadata table:\n");
+    printMetadataTable(metadata->table);
+}
+
+
+int main(int argc, char* argv[])
+{
+    // Test A - Read config file with overwrite set true
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Read config file with overwrite set true");
+    psMetadata *metadata1 = NULL;
+    int failedLines1 = 0;
+    failedLines1 = psMetadataParseConfig(&metadata1, "test.config", true);
+    printf("Failed lines: %d Expected: 6\n", failedLines1);
+    printMetadata(metadata1);
+    printFooter(stdout, "psMetadata", "Test A - Read config file with overwrite set true", true);
+
+
+    // Test B - Read config file with overwrite set false
+    printPositiveTestHeader(stdout, "psMetadata", "Test B - Read config file with overwrite set false");
+    psMetadata *metadata2 = NULL;
+    int failedLines2 = 0;
+    failedLines2 = psMetadataParseConfig(&metadata2, "test.config", false);
+    printf("Failed lines: %d Expected: 7", failedLines2);
+    printMetadata(metadata2);
+    printFooter(stdout, "psMetadata", "Test B - Read config file with overwrite set false", true);
+
+
+    // Test C - Read config file without auto-allocation of metadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test C - Read config file without auto-allocation of metadata");
+    psMetadata *metadata3 = psMetadataAlloc();
+    int failedLines3 = 0;
+    failedLines3 = psMetadataParseConfig(&metadata3, "test.config", false);
+    printf("Failed lines: %d Expected: 7", failedLines3);
+    printMetadata(metadata3);
+    printFooter(stdout, "psMetadata", "Test C - Read config file without auto-allocation of metadata", true);
+
+
+    // Test D - Attempt to use null fileName argument
+    printNegativeTestHeader(stdout,"psMetadataIO", "Test D - Attempt to use null fileName argument",
+                            "Null failedLines not allowed", 0);
+    psMetadataParseConfig(&metadata1, NULL, true);
+    printFooter(stdout, "psMetadata", "Test D - Attempt to use null fileName argument", true);
+
+
+    // Test E - Attempt to open nonexistant file
+    printNegativeTestHeader(stdout,"psMetadataIO", "Test E - Attempt to open nonexistant file",
+                            "Error opening file", 0);
+    psMetadataParseConfig(&metadata1, "abcedfg", true);
+    printFooter(stdout, "psMetadata", "Test E - Attempt to open nonexistant file", true);
+
+
+    // Test F - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test F - Free psMetadata");
+    psFree(metadata1);
+    psFree(metadata2);
+    psFree(metadata3);
+    psMemCheckLeaks(0, NULL, stdout);
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test F - Free psMetadata", true);
+
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/collections/tst_psMetadata_01.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psMetadata_01.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psMetadata_01.c	(revision 2163)
@@ -0,0 +1,271 @@
+/** @file  tst_psMetadata_01.c
+*
+*  @brief Test driver for psMetadata functions
+*
+*  This test driver contains the following tests for psMetadata:
+*     Test A - Read 1st hdr from simple FITS file
+*     Test B - Read 2nd hdr from complex FITS file
+*     Test C - Read named hdr from complex FITS file
+*     Test D - Remove items with same name from all metadata
+*     Test E - Attempt to use null file descriptor
+*     Test F - Attempt to open nonexistant file
+*     Test G - Attempt to use two null inputs
+*     Test H - Attempt to use bad extNum
+*     Test I - Attempt to use bad extNameTest
+*     Test J - Free psMetadataData
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.12 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-10-15 19:26:31 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *metadataItem, char *spaces);
+
+static void printMetadataItemList(psList *metadataItemList)
+{
+    psMetadataItem *entryChild = NULL;
+
+    psListSetIterator(metadataItemList, PS_LIST_HEAD);
+    entryChild = psListGetCurrent(metadataItemList);
+    while (entryChild != NULL) {
+        printMetadataItem(entryChild, "    ");
+        entryChild = psListGetNext(metadataItemList);
+    }
+}
+
+static void printMetadataList(psList *metadataItemList)
+{
+    psMetadataItem *entryChild = NULL;
+
+    psListSetIterator(metadataItemList, PS_LIST_HEAD);
+    entryChild = psListGetCurrent(metadataItemList);
+    while (entryChild != NULL) {
+        printMetadataItem(entryChild, " ");
+        entryChild = psListGetNext(metadataItemList);
+    }
+}
+static void printMetadataItem(psMetadataItem *metadataItem, char *spaces)
+{
+    printf("%sKey Name: %8s  ", spaces, metadataItem->name);
+    printf("Key Type: %2d  ", metadataItem->type);
+
+    switch (metadataItem->type ) {
+    case PS_META_ITEM_SET:
+        printf("Key Value: %17c", ' ');
+        break;
+    case PS_META_BOOL:
+        printf("Key Value: %15d  ", metadataItem->data.B);
+        break;
+    case PS_META_S32:
+        printf("Key Value: %15d  ", metadataItem->data.S32);
+        break;
+    case PS_META_F32:
+        printf("Key Value: %15.3f  ", metadataItem->data.F32);
+        break;
+    case PS_META_F64:
+        printf("Key Value: %15.3f  ", metadataItem->data.F64);
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)metadataItem->data.V);
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        printf("Value: unknown ");
+        break;
+    default:
+        printf("Bad type: %d ", metadataItem->type);
+    }
+    printf("Key Comment: %s\n", metadataItem->comment);
+
+    if(metadataItem->items->size) {
+        printMetadataItemList(metadataItem->items);
+    }
+}
+
+static void printMetadataTable(psHash *mdTable)
+{
+    int i;
+    psHashBucket* ptr = NULL;
+    for(i=0; i<mdTable->nbucket; i++) {
+        ptr = mdTable->buckets[i];
+        while (ptr != NULL) {
+            printMetadataItem(ptr->data, " ");
+            ptr = ptr->next;
+        }
+    }
+}
+
+static void printMetadata(psMetadata *metadata)
+{
+    printf("Contents of metadata list:\n");
+    printMetadataList(metadata->list);
+    printf("\nContents of metadata table:\n");
+    printMetadataTable(metadata->table);
+}
+
+
+int main(int argc, char* argv[])
+{
+    psMetadata *metadata1 = NULL;
+    psMetadata *metadata2 = NULL;
+    psMetadata *metadata3 = NULL;
+
+
+    // Test A - Read 1st hdr from simple FITS file
+
+    /* Header contents for header_1.fits:
+
+        SIMPLE  =                    T / file does conform to FITS standard
+        BITPIX  =                    8 / number of bits per data pixel
+        NAXIS   =                    0 / number of data axes
+        HISTORY File modified by user 'harman' with fv  on 2004-08-04T11:11:18
+        END
+    */
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Read 1st hdr from simple FITS file");
+    metadata1 = psMetadataReadHeader(metadata1, NULL, 1, "header_1.fits");
+    printMetadata(metadata1);
+    printFooter(stdout, "psMetadata", "Test A - Read 1st hdr from simple FITS file", true);
+
+
+    // Test B - Read 2nd hdr from complex FITS file
+
+    /* Header contents for header_2.fits:
+
+        SIMPLE  =                    T / file does conform to FITS standard
+        BITPIX  =                  -64 / number of bits per data pixel
+        NAXIS   =                    1 / number of data axes
+        NAXIS1  =                   64 / length of data axis 1
+        EXTEND  =                    T / FITS dataset may contain extensions
+        COMMENT   FITS (Flexible Image Transport System) format is defined in 'Astronomy
+        COMMENT   and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H
+        END
+        <DATA>
+
+        XTENSION= 'IMAGE   '           / IMAGE extension
+        BITPIX  =                  -64 / number of bits per data pixel
+        NAXIS   =                    1 / number of data axes
+        NAXIS1  =                   64 / length of data axis 1
+        PCOUNT  =                    0 / required keyword; must = 0
+        GCOUNT  =                    1 / required keyword; must = 1
+        BITPIX  =                  -64 / number of bits per data pixel
+        EXTNAME = 'MY_DATA_1'
+        HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:14:45
+        HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:15:29
+        HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:21:18
+        HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:21:46
+        END
+        <DATA>
+
+        XTENSION= 'IMAGE   '           / IMAGE extension
+        BITPIX  =                  -64 / number of bits per data pixel
+        NAXIS   =                    1 / number of data axes
+        NAXIS1  =                   64 / length of data axis 1
+        PCOUNT  =                    0 / required keyword; must = 0
+        GCOUNT  =                    1 / required keyword; must = 1
+        EXTNAME = 'MY_DATA_2'
+        HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:22:12
+        HISTORY File modified by user 'harman' with fv  on 2004-08-04T13:22:52
+        END
+        <DATA>
+    */
+    printPositiveTestHeader(stdout, "psMetadata", "Test B - Read 2nd hdr from complex FITS file");
+    metadata2 = psMetadataReadHeader(metadata2, NULL, 2, "header_2.fits");
+    printMetadata(metadata2);
+    printFooter(stdout, "psMetadata", "Test B - Read 2nd hdr from complex FITS file", true);
+
+
+    // Test C - Read named hdr from complex FITS file
+    printPositiveTestHeader(stdout, "psMetadata", "Test C - Read named hdr from complex FITS file");
+    metadata3 = psMetadataReadHeader(metadata3, "MY_DATA_2", -1, "header_2.fits");
+    printMetadata(metadata3);
+    printFooter(stdout, "psMetadata", "Test C - Read named hdr from complex FITS file", true);
+
+
+    // Test D - Remove items with same name from all metadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test D - Remove items with same name from all metadata");
+    printf("Removed HISTORY from all metadata from prior test. Resulting metadata:\n\n");
+    psMetadataRemove(metadata3, 0, "HISTORY");
+    printMetadata(metadata3);
+    printFooter(stdout, "psMetadata", "Test D - Remove items with same name from all metadata", true);
+
+
+    // Test E - Attempt to use null file filename
+    printNegativeTestHeader(stdout,"psMetadata", "Test E - Attempt to use null filename",
+                            "Null fileName not allowed", 0);
+    psMetadataReadHeader(NULL, NULL, 1, NULL);
+    printFooter(stdout, "psMetadata", "Test E - Attempt to use null filename", true);
+
+
+    // Test F - Attempt to open nonexistant file
+    printNegativeTestHeader(stdout,"psMetadata", "Test F - Attempt to open nonexistant file",
+                            "FITS error while opening file: missing.dat...Couldn't close FITS file...", 0);
+    psMetadataReadHeader(NULL, NULL, 1, "missing.dat");
+    printFooter(stdout, "psMetadata", "Test F - Attempt to open nonexistant file", true);
+
+
+    // Test G - Attempt to use two null inputs
+    printNegativeTestHeader(stdout,"psMetadata", "Test G - Attempt to use two null inputs",
+                            "Null extName and extNum = 0 not allowed", 0);
+    psMetadataReadHeader(NULL, NULL, 0, "header_2.fits");
+    printFooter(stdout, "psMetadata", "Test G - Attempt to use two null inputs", true);
+
+
+    // Test H - Attempt to use bad extNum
+    printNegativeTestHeader(stdout,"psMetadata", "Test H - Attempt to use bad extNum",
+                            "FITS error while locating header 22: tried to move past end of file", 0);
+    metadata1 = psMetadataReadHeader(metadata1, NULL, 22, "header_2.fits");
+    if (metadata1 != NULL ) {
+        psError(__func__,"psMetadataReadHeader did not return null when invalid ext given.");
+        return 10;
+    }
+    printFooter(stdout, "psMetadata", "Test H - Attempt to use bad extNum", true);
+
+
+    // Test I - Attempt to use bad extName
+    printNegativeTestHeader(stdout,"psMetadata", "Test I - Attempt to use bad extName",
+                            "FITS error while locating header AARGH: illegal HDU number", 0);
+    metadata1 = psMetadataReadHeader(NULL, "AARGH", -1, "header_2.fits");
+    if (metadata1 != NULL ) {
+        psError(__func__,"psMetadataReadHeader did not return null invalid extname give.");
+        return 11;
+    }
+    printFooter(stdout, "psMetadata", "Test I - Attempt to use bad extName", true);
+
+
+    // Test I1 - Attempt to use a valid named extension with invalid extnum
+    printNegativeTestHeader(stdout, "psMetadata", "Test I1 - Read named hdr w/ invalid extnum",
+                            "If extName specified, extNum should be -1.", 0);
+    metadata1 = psMetadataReadHeader(NULL, "MY_DATA_2", 0, "header_2.fits");
+    if (metadata1 != NULL ) {
+        psError(__func__,"psMetadataReadHeader did not return null w/ valid extname, invalid extnum");
+        return 12;
+    }
+    printFooter(stdout, "psMetadata", "Test C - Read named hdr from complex FITS file", true);
+
+
+    // Test J - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test J - Free psMetadata");
+    psFree(metadata1);
+    psFree(metadata2);
+    psFree(metadata3);
+    psMemCheckLeaks(0, NULL, stdout);
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test J - Free psMetadata", true);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/collections/tst_psMetadata_02.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psMetadata_02.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psMetadata_02.c	(revision 2163)
@@ -0,0 +1,145 @@
+/** @file  tst_psMetadata_02.c
+*
+*  @brief Test driver for psMetadata functions
+*
+*  This test driver contains the following tests for psMetadata:
+*     Test A - Allocate metadata items
+*     Test B - Attempt to create metadata item with null name
+*     Test C - Attempt to create metadata item with invalid type
+*     Test D - Allocate metadata
+*     Test E - Attempt to add metadata item to null metadata
+*     Test F - Attempt to add null metadata item to metadata
+*     Test G - Free psMetadata
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-10-07 22:31:31 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *item)
+{
+    printf("Key Name: %8s  ", item->name);
+    printf("Key Type: %2d  ", item->type);
+
+    switch (item->type ) {
+    case PS_META_BOOL:
+        printf("Key Value: %15d  ", item->data.B);
+        break;
+    case PS_META_S32:
+        printf("Key Value: %15d  ", item->data.S32);
+        break;
+    case PS_META_F32:
+        printf("Key Value: %15.3f  ", item->data.F32);
+        break;
+    case PS_META_F64:
+        printf("Key Value: %15.3f  ", item->data.F64);
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)item->data.V);
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        printf("Value: unknown ");
+        break;
+    default:
+        printf("Bad type: %d ", item->type);
+    }
+    printf("Key Comment: %s\n", item->comment);
+}
+
+
+int main( int argc, char* argv[] )
+{
+    psMetadataItem *item1 = NULL;
+    psMetadata *metadata = NULL;
+    psMetadataItem *item2 = NULL;
+    psMetadataItem *item3 = NULL;
+    psMetadataItem *item4 = NULL;
+    psMetadataItem *item5 = NULL;
+    psMetadataItem *badItem = NULL;
+
+
+    // Test A - Allocate metadata items
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Allocate metadata items");
+    item1 = psMetadataItemAlloc("myItem1", PS_META_BOOL, "I am a boolean", true);
+    item2 = psMetadataItemAlloc("myItem2", PS_META_S32, "I am a signed integer", 111);
+    item3 = psMetadataItemAlloc("myItem3", PS_META_F32, "I am a single precision floating point", 222.222);
+    item4 = psMetadataItemAlloc("myItem4", PS_META_F64, "I am a double precision floating point", 333.333);
+    item5 = psMetadataItemAlloc("myItem5", PS_META_STR, "I am a string", "HELLO WORLD");
+    printMetadataItem(item1);
+    printMetadataItem(item2);
+    printMetadataItem(item3);
+    printMetadataItem(item4);
+    printMetadataItem(item5);
+    printFooter(stdout, "psMetadata", "Test A - Allocate metadata items", true);
+
+
+    // Test B - Attempt to create metadata item with null name
+    printNegativeTestHeader(stdout,"psMetadata", "Test B - Attempt to create metadata item with null name",
+                            "Null value for name not allowed", 0);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should produce error for null name.");
+    badItem = psMetadataItemAlloc(NULL, PS_META_STR, "I am a string", "HELLO WORLD");
+    if (badItem != NULL) {
+        psError(__func__,"psMetadataItemAlloc did not return null with null name item.");
+        return 10;
+    }
+    printFooter(stdout, "psMetadata", "Test B - Attempt to create metadata item with null name", true);
+
+
+    // Test C - Attempt to create metadata item with invalid type
+    printNegativeTestHeader(stdout,"psMetadata", "Test C - Attempt to create metadata item with invalid type",
+                            "Invalid psMetadataType: 6", 0);
+    badItem = psMetadataItemAlloc("badItem", PS_META_IMG, "I am bad", "Bad comment");
+    printFooter(stdout, "psMetadata", "Test C - Attempt to create metadata item with invalid type", true);
+
+
+    // Test D - Allocate metadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test D - Allocate metadata");
+    metadata = psMetadataAlloc();
+    printFooter(stdout, "psMetadata", "Test D - Allocate metadata", true);
+
+
+    // Test E - Attempt add metadata item to null metadata
+    printNegativeTestHeader(stdout,"psMetadata", "Test E - Attempt to add metadata item to null metadata",
+                            "Null metadata collection not allowed", 0);
+    psMetadataAddItem(NULL, item1, PS_LIST_HEAD);
+    printFooter(stdout, "psMetadata", "Test E - Attempt to add metadata item to null metadata", true);
+
+
+    // Test F - Attempt add null metadata item to metadata
+    printNegativeTestHeader(stdout,"psMetadata", "Test F - Attempt to add null metadata item to metadata",
+                            "Null metadata item not allowed", 0);
+    psMetadataAddItem(metadata, NULL, PS_LIST_HEAD);
+    printFooter(stdout, "psMetadata", "Test F - Attempt to add null metadata item to metadata", true);
+
+
+    // Test G - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test G - Free psMetadata");
+    psFree(item1);
+    psFree(item2);
+    psFree(item3);
+    psFree(item4);
+    psFree(item5);
+    psFree(badItem);
+    psFree(metadata);
+    psMemCheckLeaks(0, NULL, stdout);
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test G - Free psMetadata", true);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/collections/tst_psMetadata_03.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psMetadata_03.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psMetadata_03.c	(revision 2163)
@@ -0,0 +1,241 @@
+/** @file  tst_psMetadata_03.c
+*
+*  @brief Test driver for psMetadata functions
+*
+*  This test driver contains the following tests for psMetadata:
+*     Test A - Allocate metadata and items
+*     Test B - Remove items from metadata by name
+*     Test C - Remove items from metadata by index
+*     Test D - Attempt to use null metadata
+*     Test E - Attempt to remove non-existant metadata item by name
+*     Test F - Attempt to remove non-existant metadata item by index
+*     Test G - Free psMetadata
+ *
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.7 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-10-08 01:33:14 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *item)
+{
+    printf("Key Name: %8s  ", item->name);
+    printf("Key Type: %2d  ", item->type);
+
+    switch (item->type ) {
+    case PS_META_BOOL:
+        printf("Key Value: %15d  ", item->data.B);
+        break;
+    case PS_META_S32:
+        printf("Key Value: %15d  ", item->data.S32);
+        break;
+    case PS_META_F32:
+        printf("Key Value: %15.3f  ", item->data.F32);
+        break;
+    case PS_META_F64:
+        printf("Key Value: %15.3f  ", item->data.F64);
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)item->data.V);
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        printf("Value: unknown ");
+        break;
+    default:
+        printf("Bad type: %d ", item->type);
+    }
+    printf("Key Comment: %s\n", item->comment);
+}
+
+
+int main( int argc, char* argv[] )
+{
+    psMetadataItem *item1 = NULL;
+    psMetadataItem *item2 = NULL;
+    psMetadataItem *item3 = NULL;
+    psMetadataItem *item4 = NULL;
+    psMetadataItem *errItem = NULL;
+    psMetadata *metadata = NULL;
+    psMetadata *errMetadata = NULL;
+    psHash *mdTable = NULL;
+    psList *mdList = NULL;
+    char *errName = NULL;
+
+    // Test A - Allocate metadata and items
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Allocate metadata items");
+    metadata = psMetadataAlloc();
+    item1 = psMetadataItemAlloc("myItem1", PS_META_BOOL, "I am a boolean", true);
+    item2 = psMetadataItemAlloc("myItem2", PS_META_S32, "I am a integer", 55);
+    item3 = psMetadataItemAlloc("myItem3", PS_META_BOOL, "I am a boolean", false);
+    item4 = psMetadataItemAlloc("myItem4", PS_META_S32, "I am a integer", 66);
+    errItem = psMetadataItemAlloc("errItem", PS_META_S32, "I am a integer", 99);
+    printMetadataItem(item1);
+    printMetadataItem(item2);
+    printMetadataItem(item3);
+    printMetadataItem(item4);
+    printFooter(stdout, "psMetadata", "Test A - Allocate metadata items", true);
+
+
+    // Test B - Remove items from metadata by name
+    printPositiveTestHeader(stdout, "psMetadata", "Test B - Remove items from metadata by name");
+    if( ! psMetadataAddItem(metadata, item1, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem did not return true when adding by name.");
+        return 10;
+    }
+    if( ! psMetadataAdd(metadata,PS_LIST_HEAD,"myItem2",PS_META_S32,"I am S32 integer",77) ) {
+        psError(__func__,"psMetadataAddItem did not return true when adding by name.");
+        return 11;
+    }
+    if ( ! psMetadataRemove(metadata, 0, "myItem1" ) ) {
+        psError(__func__,"psMetadataRemove did not return true when removing by name.");
+        return 12;
+    }
+    if ( ! psMetadataRemove(metadata, 0, "myItem2" ) ) {
+        psError(__func__,"psMetadataRemove did not return true when removing by name.");
+        return 13;
+    }
+    printFooter(stdout, "psMetadata", "Test B - Remove items from metadata by name", true);
+
+
+    // Test C - Remove items from metadata by index
+    printPositiveTestHeader(stdout, "psMetadata", "Test C - Remove items from metadata by index");
+    if ( ! psMetadataAddItem(metadata, item3, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem did not return true when adding by index.");
+        return 14;
+    }
+    if ( ! psMetadataAdd(metadata,PS_LIST_HEAD,"myItem4",PS_META_S32,"I am S32 integer",88) ) {
+        psError(__func__,"psMetadataAddItem did not return true when adding by index.");
+        return 15;
+    }
+    if( ! psMetadataRemove(metadata, 0, NULL) ) {
+        psError(__func__,"psMetadataRemove did not return true when removing by index.");
+        return 16;
+    }
+    if ( ! psMetadataRemove(metadata, 0, NULL ) ) {
+        psError(__func__,"psMetadataRemove did not return true when removing by index.");
+        return 17;
+    }
+    printFooter(stdout, "psMetadata", "Test C - Remove items from metadata by index", true);
+
+
+    // Test D - Attempt to use null metadata
+    printNegativeTestHeader(stdout,"psMetadata", "Test D - Attempt to use null metadata",
+                            "Null metadata collection not allowed", 0);
+    if ( psMetadataRemove(NULL, 0, NULL) ) {
+        psError(__func__,"psMetadataRemove did not return false when removing from null metadata.");
+        return 18;
+    }
+    printFooter(stdout, "psMetadata", "Test D - Attempt to use null metadata", true);
+
+
+    // Test E - Attempt to remove non-existant metadata item by name
+    printNegativeTestHeader(stdout,"psMetadata", "Test E - Attempt to remove non-existant metadata item by name",
+                            "Couldn't find metadata item. Name: AARGH", 0);
+    if( psMetadataRemove(metadata, 0, "AARGH") ) {
+        psError(__func__,"psMetadataRemove did not return false when removing non-existant item.");
+        return 19;
+    }
+    printFooter(stdout, "psMetadata", "Test E - Attempt to remove non-existant metadata item by name", true);
+
+
+    // Test F - Attempt to remove non-existant metadata item by index
+    printNegativeTestHeader(stdout,"psMetadata", "Test E - Attempt to remove non-existant metadata item by index",
+                            "Couldn't find metadata item in list. Index: 22", 0);
+    if( psMetadataRemove(metadata, 22, NULL) ) {
+        psError(__func__,"psMetadataRemove did not return false when removing non-existant item.");
+        return 20;
+    }
+    printFooter(stdout, "psMetadata", "Test E - Attempt to remove non-existant metadata item by index", true);
+
+
+    // Test H - Attempt to add item to an invalid metadata structure
+    printNegativeTestHeader(stdout,"psMetadata","Test H - Attempt to add item to metadata w/o hash table",
+                            "Couldn't add item to invalid metadata structure.",0);
+    errMetadata = psMetadataAlloc();
+    mdTable = errMetadata->table;
+    errMetadata->table = NULL;
+    if ( psMetadataAddItem(errMetadata, item3, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem did not return false w/ invalid metadata struct w/o hash table.");
+        return 21;
+    }
+    if ( psMetadataRemove(errMetadata, PS_LIST_HEAD, "errItem") ) {
+        psError(__func__,"psMetadataRemove did not return false w/ invalid metadata struct w/o hash table.");
+        return 31;
+    }
+    errMetadata->table = mdTable;
+    printFooter(stdout,"psMetadata","Test H - Attempt to add item to invalid metadata w/o hash table", true);
+
+    // Test J - Attempt to add item to an invalid metadata structure
+    printNegativeTestHeader(stdout,"psMetadata","Test J - Attempt to add item to metadata w/o link list",
+                            "Couldn't add item to invalid metadata structure.",0);
+    mdList = errMetadata->list;
+    errMetadata->list = NULL;
+    if ( psMetadataAddItem(errMetadata, item3, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem did not return false w/ invalid metadata struct w/o link list.");
+        return 22;
+    }
+    if ( psMetadataRemove(errMetadata, PS_LIST_HEAD, "errItem") ) {
+        psError(__func__,"psMetadataRemove did not return false w/ invalid metadata struct w/o link list.");
+        return 32;
+    }
+    errMetadata->list = mdList;
+    printFooter(stdout,"psMetadata","Test J - Attempt to add item to invalid metadata w/o link list", true);
+
+    // Test K - Attempt to add item with a null name
+    printNegativeTestHeader(stdout,"psMetadata","Test K - Attempt to add item with null name",
+                            "Couldn't add item with null name.",0);
+    errName = errItem->name;
+    errItem->name = NULL;
+    if ( psMetadataAddItem(errMetadata, errItem, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem did not return false with item with null name.");
+        return 23;
+    }
+    errItem->name = errName;
+    printFooter(stdout,"psMetadata","Test K - Attempt to add item with null name", true);
+
+    // Test L - Attempt to add item to an invalid metadata structure
+    printNegativeTestHeader(stdout,"psMetadata","Test L - Attempt to add item to metadata w/o hash table",
+                            "Couldn't add item to invalid metadata structure.",0);
+    mdTable = errMetadata->table;
+    errMetadata->table = NULL;
+    if ( psMetadataAdd(errMetadata, PS_LIST_HEAD, "errItem", PS_META_S32,"Integer",22) ) {
+        psError(__func__,"psMetadataAddItem did not return false w/ invalid metadata struct w/o hash table.");
+        return 24;
+    }
+    errMetadata->table = mdTable;
+    printFooter(stdout,"psMetadata","Test L - Attempt to add item to invalid metadata w/o hash table", true);
+
+    // Test G - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test G - Free psMetadata");
+    psFree(metadata);
+    psFree(item1);
+    psFree(item2);
+    psFree(item3);
+    psFree(item4);
+    psFree(errItem);
+    psFree(errMetadata);
+    if( psMemCheckLeaks(0, NULL, stdout) != 0 ) {
+        psError(__func__,"Memory leaks detected.");
+        return 25;
+    }
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test G - Free psMetadata", true);
+
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/collections/tst_psMetadata_04.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psMetadata_04.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psMetadata_04.c	(revision 2163)
@@ -0,0 +1,212 @@
+
+/** @file  tst_psMetadata_04.c
+*
+*  @brief Test driver for psMetadata functions
+*
+*  This test driver contains the following tests for psMetadata:
+*     Test A - Allocate metadata and items
+*     Test B - Lookup metadata item by name
+*     Test C - Attempt to use null metadata
+*     Test D - Attempt to use null key
+*     Test E - Attempt to lookup non-existant metadata item
+*     Test F - Lookup metadata item by index
+*     Test G - Attempt to use null metadata
+*     Test H - Attempt to get non-existant metadata item
+*     Test I - Free psMetadata
+*     Test J - Attempt to look up with an invalid metadata object
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-10-08 20:53:21 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *item)
+{
+    printf("Key Name: %8s  ", item->name);
+    printf("Key Type: %2d  ", item->type);
+
+    switch (item->type ) {
+    case PS_META_BOOL:
+        printf("Key Value: %15d  ", item->data.B);
+        break;
+    case PS_META_S32:
+        printf("Key Value: %15d  ", item->data.S32);
+        break;
+    case PS_META_F32:
+        printf("Key Value: %15.3f  ", item->data.F32);
+        break;
+    case PS_META_F64:
+        printf("Key Value: %15.3f  ", item->data.F64);
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)item->data.V);
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        printf("Value: unknown ");
+        break;
+    default:
+        printf("Bad type: %d ", item->type);
+    }
+    printf("Key Comment: %s\n", item->comment);
+}
+
+
+int main( int argc, char* argv[] )
+{
+    psMetadataItem *item1 = NULL;
+    psMetadataItem *item2 = NULL;
+    psMetadataItem *item3 = NULL;
+    psMetadataItem *item4 = NULL;
+    psMetadataItem *item = NULL;
+    psMetadata *metadata = NULL;
+    psHash* tmpTable = NULL;
+    psList* tmpList = NULL;
+
+    // Test A - Allocate metadata and items
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Allocate metadata items");
+    metadata = psMetadataAlloc();
+    item1 = psMetadataItemAlloc("myItem1", PS_META_BOOL, "I am a boolean", true);
+    item2 = psMetadataItemAlloc("myItem2", PS_META_S32, "I am a integer", 55);
+    item3 = psMetadataItemAlloc("myItem3", PS_META_BOOL, "I am a boolean", false);
+    item4 = psMetadataItemAlloc("myItem4", PS_META_S32, "I am a integer", 66);
+    printMetadataItem(item1);
+    printMetadataItem(item2);
+    printMetadataItem(item3);
+    printMetadataItem(item4);
+    psMetadataAddItem(metadata, item1, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item2, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item3, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item4, PS_LIST_HEAD);
+    printFooter(stdout, "psMetadata", "Test A - Allocate metadata items", true);
+
+
+    // Test B - Lookup metadata item by name
+    printPositiveTestHeader(stdout, "psMetadata", "Test B - Lookup metadata item by name");
+    item = psMetadataLookup(metadata, "myItem2");
+    printf("Found item named %s\n", item->name);
+    if(item == NULL) {
+        printf("ERROR: Item should not be null\n");
+        return 10;
+    }
+    printFooter(stdout, "psMetadata", "Test B - Lookup metadata item by name", true);
+
+
+    // Test C - Attempt to use null metadata
+    printNegativeTestHeader(stdout,"psMetadata", "Test C - Attempt to use null metadata",
+                            "Null metadata collection not allowed", 0);
+    if ( psMetadataLookup(NULL, "myItem2") != NULL ) {
+        psError(__func__,"psMetadataLookup did not return NULL with null metadata.");
+        return 11;
+    }
+    printFooter(stdout, "psMetadata", "Test C - Attempt to use null metadata", true);
+
+
+    // Test D - Attempt to use null key
+    printNegativeTestHeader(stdout,"psMetadata", "Test D - Attempt to use null key",
+                            "Null key name not allowed", 0);
+    if ( psMetadataLookup(metadata, NULL) != NULL ) {
+        psError(__func__,"psMetadata did not return NULL with null key.");
+        return 12;
+    }
+    printFooter(stdout, "psMetadata", "Test D - Attempt to use null key", true);
+
+
+    // Test E - Attempt to lookup non-existant metadata item
+    printNegativeTestHeader(stdout,"psMetadata", "Test E - Attempt to lookup non-existant metadata item",
+                            "Couldn't find metadata item. Name: AARGH", 0);
+    if ( psMetadataLookup(metadata, "AARGH") != NULL ) {
+        psError(__func__,"psMetadata did not return NULL with a non-existant item.");
+        return 13;
+    }
+    printFooter(stdout, "psMetadata", "Test E - Attempt to lookup non-existant metadata item", true);
+
+
+    // Test F - Lookup metadata item by index
+    printPositiveTestHeader(stdout, "psMetadata", "Test F - Lookup metadata item by index");
+    item = psMetadataGet(metadata, 0);
+    printf("Found item named %s\n", item->name);
+    if(item == NULL) {
+        printf("ERROR: Item should not be null\n");
+        return 14;
+    }
+    printFooter(stdout, "psMetadata", "Test F - Lookup metadata item by index", true);
+
+
+    // Test G - Attempt to use null metadata
+    printNegativeTestHeader(stdout,"psMetadata", "Test G - Attempt to use null metadata",
+                            "Null metadata collection not allowed", 0);
+    item = psMetadataGet(NULL, 0);
+    if ( item != NULL ) {
+        psError(__func__,"psMetadataGet did not return NULL with null metadata structure.");
+        return 15;
+    }
+    printFooter(stdout, "psMetadata", "Test G - Attempt to use null metadata", true);
+
+
+    // Test H - Attempt to get non-existant metadata item
+    printNegativeTestHeader(stdout,"psMetadata", "Test H - Attempt to get non-existant metadata item",
+                            "Couldn't find metadata item with given index. Index: 22", 0);
+    if ( psMetadataGet(metadata, 22) != NULL ) {
+        psError(__func__,"psMetadataGet did not return NULL with non-existant metadata item.");
+        return 16;
+    }
+    printFooter(stdout, "psMetadata", "Test H - Attempt to get non-existant metadata item", true);
+
+    // Test J - Attempt to look up with an invalid metadata object
+    printNegativeTestHeader(stdout,"psMetadata","Test J - Attemp to look up with an invalid metadata",
+                            "Lookup item with invalid metadata object.", 0 );
+    tmpTable = metadata->table;
+    metadata->table = NULL;
+    if ( psMetadataLookup(metadata,"myItem2") != NULL ) {
+        psError(__func__,"psMetadataLookup did not return null for invalid metadata object.");
+        return 20;
+    }
+    metadata->table = tmpTable;
+    printFooter(stdout, "psMetadata","Test J - Attempt to lookup an invalid metadata object.",true);
+
+    // Test K - Attempt get item  with an invalid metadata object
+    printNegativeTestHeader(stdout,"psMetadata","Test K - Attemp to get item with an invalid metadata",
+                            "Get item with invalid metadata object.", 0 );
+    tmpList = metadata->list;
+    metadata->list = NULL;
+    if ( psMetadataGet(metadata,0) != NULL ) {
+        psError(__func__,"psMetadataLookup did not return null for invalid metadata object.");
+        return 20;
+    }
+    metadata->list = tmpList;
+    printFooter(stdout, "psMetadata","Test K - Attempt to get item with  invalid metadata object.",true);
+
+    // Test I - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test I - Free psMetadata");
+    psFree(metadata);
+    psFree(item1);
+    psFree(item2);
+    psFree(item3);
+    psFree(item4);
+    if ( psMemCheckLeaks(0, NULL, stdout) != 0 ) {
+        psError(__func__,"memory leaks detected.");
+        return 20;
+    }
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+        return 21;
+    }
+    printFooter(stdout, "psMetadata", "Test I - Free psMetadata", true);
+
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/collections/tst_psMetadata_05.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psMetadata_05.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psMetadata_05.c	(revision 2163)
@@ -0,0 +1,282 @@
+
+
+/** @file  tst_psMetadata_05.c
+*
+*  @brief Test driver for psMetadata functions
+*
+*  This test driver contains the following tests for psMetadata:
+*     Test A - Allocate metadata and items
+*     Test B - Set iterator at second index
+*     Test C - Get next item at index
+*     Test D - Get next item at index and string
+*     Test E - Get previous item at index
+*     Test F - Write metadata item to file
+*     Test G - Attempt to use null metadata with setIterator
+*     Test H - Attempt to use null metadata with getNext
+*     Test I - Attempt to use null metadata with getPrevious
+*     Test J - Attempt to use null file with itemPrint
+*     Test K - Attempt to use null format with itemPrint
+*     Test L - Attempt to use null item with itemPrint
+*     Test M - Free psMetadata
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.7 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-10-12 01:40:32 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *item)
+{
+    printf("Key Name: %8s  ", item->name);
+    printf("Key Type: %2d  ", item->type);
+
+    switch (item->type ) {
+    case PS_META_BOOL:
+        printf("Key Value: %15d  ", item->data.B);
+        break;
+    case PS_META_S32:
+        printf("Key Value: %15d  ", item->data.S32);
+        break;
+    case PS_META_F32:
+        printf("Key Value: %15.3f  ", item->data.F32);
+        break;
+    case PS_META_F64:
+        printf("Key Value: %15.3f  ", item->data.F64);
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)item->data.V);
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        printf("Value: unknown ");
+        break;
+    default:
+        printf("Bad type: %d ", item->type);
+    }
+    printf("Key Comment: %s\n", item->comment);
+}
+
+
+int main( int argc, char* argv[] )
+{
+    long data;
+    psF32 fpdata;
+    psMetadataItem *item1 = NULL;
+    psMetadataItem *item2 = NULL;
+    psMetadataItem *item3 = NULL;
+    psMetadataItem *item4 = NULL;
+    psMetadataItem *item5 = NULL;
+    psMetadataItem *item6 = NULL;
+    psMetadataItem *item7 = NULL;
+    psMetadataItem *item8 = NULL;
+    psMetadataItem *item = NULL;
+    psMetadata *metadata = NULL;
+    FILE *fd = NULL;
+    char str[7];
+    psList* tmpList = NULL;
+
+    // Test A - Allocate metadata and items
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Allocate metadata items");
+    metadata = psMetadataAlloc();
+    item1 = psMetadataItemAlloc("myItem1", PS_META_BOOL, "I am a boolean", true);
+    item2 = psMetadataItemAlloc("myItem2", PS_META_S32, "I am a integer", 55);
+    item3 = psMetadataItemAlloc("myItem3", PS_META_BOOL, "I am a boolean", false);
+    item4 = psMetadataItemAlloc("myItem4", PS_META_S32, "I am a integer", 66);
+    item5 = psMetadataItemAlloc("myItem5", PS_META_F32, "I am a float", 3.14);
+    item6 = psMetadataItemAlloc("myItem6", PS_META_F64, "I am a double", 6.28);
+    item7 = psMetadataItemAlloc("myItem7", PS_META_STR, "I am a string", "GNIRTS");
+    item8 = psMetadataItemAlloc("myItem8", PS_META_UNKNOWN, "I am unknown");
+    printMetadataItem(item1);
+    printMetadataItem(item2);
+    printMetadataItem(item3);
+    printMetadataItem(item4);
+    psMetadataAddItem(metadata, item1, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item2, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item3, PS_LIST_HEAD);
+    psMetadataAddItem(metadata, item4, PS_LIST_HEAD);
+    printFooter(stdout, "psMetadata", "Test A - Allocate metadata items", true);
+
+
+    // Test B - Set iterator at second index
+    printPositiveTestHeader(stdout, "psMetadata", "Test B - Set iterator at second index");
+    psMetadataSetIterator(metadata, 2);
+    printFooter(stdout, "psMetadata", "Test B - Set iterator at second index", true);
+
+
+    // Test C - Get next item at index
+    printPositiveTestHeader(stdout, "psMetadata", "Test C - Get next item at index");
+    item = psMetadataGetNext(metadata, NULL, 2);
+    if(item == NULL) {
+        printf("ERROR: Item should not be null\n");
+    } else {
+        printf("Found item named %s\n", item->name);
+    }
+    printFooter(stdout, "psMetadata", "Test C - Get next item at index", true);
+
+
+    // Test D - Get next item at index and string
+    printPositiveTestHeader(stdout, "psMetadata", "Test D - Get next item at index and string");
+    item = psMetadataGetNext(metadata, "myItem1", 1);
+    if(item == NULL) {
+        printf("ERROR: Item should not be null\n");
+    } else {
+        printf("Found item named %s\n", item->name);
+    }
+    printFooter(stdout, "psMetadata", "Test D - Get next item at index and string", true);
+
+
+    // Test E - Get previous item at index
+    printPositiveTestHeader(stdout, "psMetadata", "Test E - Get previous item at index");
+    item = psMetadataGetPrevious(metadata, NULL, 1);
+    if(item == NULL) {
+        printf("ERROR: Item should not be null\n");
+    } else {
+        printf("Found item named %s\n", item->name);
+    }
+    if( psMetadataGetPrevious(metadata,"myItem3",1) == NULL) {
+        psError(__func__,"psMetadataGetPrevious did not return an item from metadata.");
+        return 45;
+    }
+    tmpList = metadata->list;
+    metadata->list = NULL;
+    if ( psMetadataGetPrevious(metadata,NULL,1) != NULL) {
+        psError(__func__,"psMetadataGetPrevious did not return null for invalid metadata.");
+        return 50;
+    }
+    metadata->list = tmpList;
+    printFooter(stdout, "psMetadata", "Test E - Get previous item at index", true);
+
+
+    // Test F - Write metadata item to file
+    printPositiveTestHeader(stdout, "psMetadata", "Test F - Write metadata item to file");
+    fd = fopen("./tst_psMetadata05_OUT", "w");
+    if(fd == NULL) {
+        printf("ERROR: Couldn't open file for writing\n");
+    }
+    psMetadataItemPrint(fd, "S32  = %ld\n", item2);
+    psMetadataItemPrint(fd, "BOL  = %ld\n", item3);
+    psMetadataItemPrint(fd, "F32  = %g\n", item5);
+    psMetadataItemPrint(fd, "F64  = %g\n", item6);
+    psMetadataItemPrint(fd, "STR  = %s\n", item7);
+    psMetadataItemPrint(fd, "UNK  = \n", item8);
+    printFooter(stdout, "psMetadata", "Test F - Write metadata item to file", true);
+    fclose(fd);
+    fd = fopen("./tst_psMetadata05_OUT", "r");
+    if(fd == NULL) {
+        printf("ERROR: Couldn't open file for reading\n");
+    }
+    fscanf(fd, "S32 = %ld\n", &data);
+    if(data != 55) {
+        printf("ERROR: Data in file is not as expected. Value: %ld. Should be: 55.\n", data);
+    }
+    fscanf(fd, "BOL = %ld\n", &data);
+    if(data != 0) {
+        printf("ERROR: Data in file is not as expected. Value: %ld. Should be: 0.\n", data);
+    }
+    fscanf(fd, "F32 = %g\n", &fpdata);
+    if ( (fpdata <= 3.1) || (fpdata >= 3.2) ) {
+        printf("ERROR: Data in file is not as expected. Value: %g. Should be: 3.14.\n", fpdata);
+    }
+    fscanf(fd, "F64 = %g\n", &fpdata);
+    if ( (fpdata <= 6.2) || ( fpdata >= 6.3) ) {
+        printf("ERROR: Data in file is not as expected. Value: %g. Should be: 6.28.\n", fpdata);
+    }
+    fscanf(fd, "STR = %s\n", str);
+    if ( strcmp(str,"GNIRTS") != 0 ) {
+        printf("ERROR: Data is file is not as expected. Value: %s. Should be: GNIRTS.\n", str);
+    }
+    fclose(fd);
+
+    // Test G - Attempt to use null metadata with setIterator
+    printNegativeTestHeader(stdout,"psMetadata", "Test G - Attempt to use null metadata with setIterator",
+                            "Null metadata collection not allowed", 0);
+    psMetadataSetIterator(NULL, 0);
+    tmpList = metadata->list;
+    metadata->list = NULL;
+    psMetadataSetIterator(metadata,0);
+    metadata->list = tmpList;
+    printFooter(stdout, "psMetadata", "Test G - Attempt to use null metadata with setIterator", true);
+
+
+    // Test H - Attempt to use null metadata with getNext
+    printNegativeTestHeader(stdout,"psMetadata", "Test H - Attempt to use null metadata with getNext",
+                            "Null metadata collection not allowed", 0);
+    if( psMetadataGetNext(NULL, "myItem2", 0) != NULL ) {
+        psError(__func__,"psMetadataGetNext did not return null for null metadata.");
+        return 40;
+    }
+    tmpList = metadata->list;
+    metadata->list = NULL;
+    if ( psMetadataGetNext(metadata, "myItem2", 0) != NULL ) {
+        psError(__func__,"psMetadataGetNext did not return null for invalid metadata.");
+        return 41;
+    }
+    metadata->list = tmpList;
+
+    printFooter(stdout, "psMetadata", "Test H - Attempt to use null metadata with getNext", true);
+
+
+    // Test I - Attempt to use null metadata with getPrevious
+    printNegativeTestHeader(stdout,"psMetadata", "Test I - Attempt to use null metadata with getPrevious",
+                            "Null metadata collection not allowed", 0);
+    psMetadataGetPrevious(NULL, "myItem2", 0);
+    printFooter(stdout, "psMetadata", "Test I - Attempt to use null metadata with getPrevious", true);
+
+
+    // Test J - Attempt to use null file with itemPrint
+    printNegativeTestHeader(stdout,"psMetadata", "Test J - Attempt to use null file with itemPrint",
+                            "Null file descriptor not allowed", 0);
+    psMetadataItemPrint(NULL, "Item value: %ld", item2);
+    printFooter(stdout, "psMetadata", "Test J - Attempt to use null file with itemPrint", true);
+
+
+    // Test K - Attempt to use null format with itemPrint
+    printNegativeTestHeader(stdout,"psMetadata", "Test K - Attempt to use null format with itemPrint",
+                            "Null format not allowed", 0);
+    psMetadataItemPrint(fd, NULL, item2);
+    printFooter(stdout, "psMetadata", "Test K - Attempt to use null format with itemPrint", true);
+
+
+    // Test L - Attempt to use null item with itemPrint
+    printNegativeTestHeader(stdout,"psMetadata", "Test L - Attempt to use null item with itemPrint",
+                            "Null metadata not allowed", 0);
+    psMetadataItemPrint(fd, "Item value: %ld", NULL);
+    printFooter(stdout, "psMetadata", "Test L - Attempt to use null item with itemPrint", true);
+
+
+    // Test M - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test M - Free psMetadata");
+    psFree(metadata);
+    psFree(item1);
+    psFree(item2);
+    psFree(item3);
+    psFree(item4);
+    psFree(item5);
+    psFree(item6);
+    psFree(item7);
+    psFree(item8);
+    if ( psMemCheckLeaks(0, NULL, stdout) != 0 ) {
+        psError(__func__,"Memory leaks detected.");
+        return 50;
+    }
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+        return 51;
+    }
+    printFooter(stdout, "psMetadata", "Test M - Free psMetadata", true);
+
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/collections/tst_psMetadata_06.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psMetadata_06.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psMetadata_06.c	(revision 2163)
@@ -0,0 +1,144 @@
+
+/** @file  tst_psMetadata_06.c
+*
+*  @brief Test driver for psMetadata functions
+*
+*  This test driver contains the following tests for psMetadata:
+*     Test A - Allocate metadata and items
+*     Test B - Add leaf node on top of existing leaf node
+*     Test C - Add leaf node to existing folder node
+*     Test D - Add folder node on top of existing leaf node
+*     Test E - Free psMetadata
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.3 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-10-12 01:54:00 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+#include <string.h>
+
+static void printMetadataItem(psMetadataItem *item)
+{
+    printf("Key Name: %8s  ", item->name);
+    printf("Key Type: %2d  ", item->type);
+
+    switch (item->type ) {
+    case PS_META_BOOL:
+        printf("Key Value: %15d  ", item->data.B);
+        break;
+    case PS_META_S32:
+        printf("Key Value: %15d  ", item->data.S32);
+        break;
+    case PS_META_F32:
+        printf("Key Value: %15.3f  ", item->data.F32);
+        break;
+    case PS_META_F64:
+        printf("Key Value: %15.3f  ", item->data.F64);
+        break;
+    case PS_META_STR:
+        printf("Key Value: %15s  ", (char*)item->data.V);
+        break;
+    case PS_META_IMG:
+    case PS_META_JPEG:
+    case PS_META_PNG:
+    case PS_META_ASTROM:
+    case PS_META_UNKNOWN:
+        printf("Value: unknown ");
+        break;
+    default:
+        printf("Bad type: %d ", item->type);
+    }
+    printf("Key Comment: %s\n", item->comment);
+}
+
+
+int main( int argc, char* argv[] )
+{
+    psMetadataItem *item1a = NULL;
+    psMetadataItem *item1b = NULL;
+    psMetadataItem *item1c = NULL;
+    psMetadataItem *item2a = NULL;
+    psMetadataItem *item2b = NULL;
+    psMetadata *metadata = NULL;
+
+
+    // Test A - Allocate metadata and items
+    printPositiveTestHeader(stdout, "psMetadata", "Test A - Allocate metadata and items");
+    item1a = psMetadataItemAlloc("myItem1", PS_META_BOOL, "I am a boolean", true);
+    item1b = psMetadataItemAlloc("myItem1", PS_META_S32, "I am a signed integer", 111);
+    item1c = psMetadataItemAlloc("myItem1", PS_META_S32, "I am a signed integer", 222);
+    item2a = psMetadataItemAlloc("myItem2", PS_META_S32, "I am a signed integer", 333);
+    item2b = psMetadataItemAlloc("myItem2", PS_META_ITEM_SET, "I am a folder node", NULL);
+    metadata = psMetadataAlloc();
+    printMetadataItem(item1a);
+    printMetadataItem(item1b);
+    printMetadataItem(item1c);
+    printMetadataItem(item2a);
+    printMetadataItem(item2b);
+    printFooter(stdout, "psMetadata", "Test A - Allocate metadata and items", true);
+
+
+    // Test B - Add leaf node on top of existing leaf node
+    printPositiveTestHeader(stdout, "psMetadata", "Test B - Add leaf node on top of existing leaf node");
+    if( ! psMetadataAddItem(metadata, item1a, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem returned false for adding a node top.");
+        return 20;
+    }
+    if ( ! psMetadataAddItem(metadata, item1b, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem returned false for adding a node top.");
+        return 21;
+    }
+
+    printFooter(stdout, "psMetadata", "Test B - Add leaf node on top of existing leaf node", true);
+
+
+    // Test C - Add leaf node to existing folder node
+    printPositiveTestHeader(stdout, "psMetadata", "Test C - Add leaf node to existing folder node");
+    if ( ! psMetadataAddItem(metadata, item1c, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem return false for adding a not to existing node.");
+        return 22;
+    }
+    printFooter(stdout, "psMetadata", "Test C - Add leaf node to existing folder node", true);
+
+
+    // Test D - Add folder node on top of existing leaf node
+    printPositiveTestHeader(stdout, "psMetadata", "Test D - Add folder node on top of existing leaf node");
+    if ( ! psMetadataAddItem(metadata, item2a, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem returned false for adding a node to existing leaf node.");
+        return 23;
+    }
+    if ( ! psMetadataAddItem(metadata, item2b, PS_LIST_HEAD) ) {
+        psError(__func__,"psMetadataAddItem returned false for adding a nod to existing leaf node.");
+        return 24;
+    }
+    printFooter(stdout, "psMetadata", "Test D - Add folder node on top of existing leaf node", true);
+
+
+    // Test E - Free psMetadata
+    printPositiveTestHeader(stdout, "psMetadata", "Test E - Free psMetadata");
+    psFree(item1a);
+    psFree(item1b);
+    psFree(item1c);
+    psFree(item2a);
+    psFree(item2b);
+    psFree(metadata);
+    if ( psMemCheckLeaks(0, NULL, stdout) != 0 ) {
+        psError(__func__,"Memory leaks detected.");
+        return 25;
+    }
+    psMemCheckCorruption(0);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMetadata", "Test E - Free psMetadata", true);
+
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/collections/tst_psVector.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psVector.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psVector.c	(revision 2163)
@@ -0,0 +1,110 @@
+/** @file  tst_psVector.c
+ *
+ *  @brief Test driver for psVector integer functions
+ *
+ *  This test driver contains the following tests for psVector test point 1:
+ *     A)  Create S32 vector
+ *     B)  Add data to S32 vector
+ *     C)  Reallocate S32 vector bigger
+ *     D)  Reallocate S32 vector smaller
+ *     E)  Free S32 vector
+ *     F)  Attempt to create a S32 vector with zero size
+ *     G)  Attempt to realloc a null S32 vector
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.4 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-09-28 23:26:49 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+
+
+    // Test A - Create S32 vector
+    printPositiveTestHeader(stdout,"psVector", "Create S32 vector");
+    psVector *psVec = psVectorAlloc(5, PS_TYPE_S32);
+    printf("Vector size = %d\n", psVec->nalloc);
+    printf("Vector type = %d\n", psVec->type.type);
+    printf("Vector dimen = %d\n", psVec->type.dimen);
+    printFooter(stdout, "psVector", "Create S32 vector", true);
+
+
+    // Test B - Add data to integer vector
+    printPositiveTestHeader(stdout, "psVector", "Add data to S32 vector");
+    for(int i = 0; i < 5; i++) {
+        psVec->data.S32[i] = i*10;
+        printf("Elem %d = %d\n", i, psVec->data.S32[i]);
+    }
+    printf("Vector size = %d\n", psVec->nalloc);
+    printf("Vector population = %d\n", psVec->n);
+    printFooter(stdout, "psVector", "Add data to S32 vector", true);
+
+
+    // Test C - Reallocate S32 vector bigger
+    printPositiveTestHeader(stdout,"psVector", "Reallocate S32 vector bigger");
+    psVec = psVectorRealloc(psVec,10);
+    printf("Adding more elements to S32 vector...\n");
+    for(int i = 5; i < 10; i++) {
+        psVec->data.S32[i] = i*10;
+        psVec->n++;
+        printf("Elem %d = %d\n", i, psVec->data.S32[i]);
+    }
+    printf("Vector size = %d\n", psVec->nalloc);
+    printf("Vector population = %d\n", psVec->n);
+    printFooter(stdout, "psVector", "Reallocate S32 vector bigger", true);
+
+
+    // Test D - Reallocate S32 vector smaller
+    printPositiveTestHeader(stdout,"psVector","Reallocate S32 vector smaller");
+    psVec = psVectorRealloc(psVec,3);
+    printf("Vector size = %d\n", psVec->nalloc);
+    for(int i = 0; i < 3; i++) {
+        printf("Elem %d = %d\n", i, psVec->data.S32[i]);
+    }
+    printf("Vector size = %d\n", psVec->nalloc);
+    printf("Vector population = %d\n", psVec->n);
+    printFooter(stdout, "psVector", "Reallocate integer S32 smaller", true);
+
+
+    // Test E - Free S32 vector
+    printPositiveTestHeader(stdout, "psVector", "Free S32 vector");
+    psFree(psVec);
+    int leaks = psMemCheckLeaks(0, NULL, stdout);
+    if(leaks != 0) {
+        printf("ERROR: Found %d memory leaks\n",leaks);
+    }
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psVector" ,"Free S32 vector", true);
+
+
+    // Test F - Attempt to create a S32 vector with zero size
+    printNegativeTestHeader(stdout,"psVector", "Attempt to create a S32 vector with zero size",
+                            "Invalid value for nalloc", 0);
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error message.");
+    psVector *vecBad = psVectorAlloc(0, PS_TYPE_S32);
+    if(vecBad != NULL) {
+        printf("ERROR: Return is not NULL\n");
+    }
+    printFooter(stdout, "psVector", "Attempt to create a S32 vector with zero size", true);
+
+
+    // Test G - Attempt to realloc a null S32 vector
+    printNegativeTestHeader(stdout,"psVector", "Attempt to realloc a null S32 vector",
+                            "Null input vector", 0);
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error message.");
+    psVectorRealloc(NULL,6);
+    printFooter(stdout, "psVector", "Attempt to realloc a null S32 vector", true);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/collections/tst_psVectorSort_01.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psVectorSort_01.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psVectorSort_01.c	(revision 2163)
@@ -0,0 +1,83 @@
+/** @file  tst_psVectorSort_01.c
+ *
+ *  @brief Test driver for psVectorSort functions
+ *
+ *  This test driver contains the following tests for psVectorSort test point 1:
+ *     A)  Create float vectors
+ *     B)  Sort input float vector and put results into output float vector
+ *     C)  Free float vectors
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.2 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-08-06 22:34:05 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+    psVector *in = NULL;
+    psVector *out = NULL;
+    psVector *tempVec = NULL;
+
+
+    // Test A - Create float vectors
+    printPositiveTestHeader(stdout,"psVectorSort", "Create float vectors");
+    in = psVectorAlloc(7, PS_TYPE_F32);
+    in->n = 7;
+    out = psVectorAlloc(7, PS_TYPE_F32);
+    out->n = 7;
+    in->data.F32[0] = 7.0f;
+    in->data.F32[1] = 9.0f;
+    in->data.F32[2] = 3.0f;
+    in->data.F32[3] = 1.0f;
+    in->data.F32[4] = 5.0f;
+    in->data.F32[5] = 5.0f;
+    in->data.F32[6] = -20.0f;
+    for(int i=0; i<7; i++) {
+        printf("vec[%d] = %f\n", i, in->data.F32[i]);
+    }
+    printFooter(stdout, "psVectorSort", "Create float vectors", true);
+
+
+    // Test B - Sort input float vector and put results into output float vector
+    printPositiveTestHeader(stdout,"psVectorSort", "Sort float vector");
+    tempVec = out;
+    out = psVectorSort(out, in);
+    for(int i=0; i<7; i++) {
+        printf("vec[%d] = %f\n", i, out->data.F32[i]);
+    }
+    if(out != tempVec) {
+        printf("Error: Return pointer not equal to output argument pointer\n");
+    }
+    printFooter(stdout, "psVectorSort", "Sort float vector", true);
+
+
+    // Test C - Sort input float vector into itself
+    printPositiveTestHeader(stdout,"psVectorSort", "Sort input float vector into itself");
+    in = psVectorSort(in, in);
+    for(int i=0; i<7; i++) {
+        printf("vec[%d] = %f\n", i, out->data.F32[i]);
+    }
+    printFooter(stdout, "psVectorSort", "Sort input float vector into itself", true);
+
+
+    // Test D - Free float vectors
+    printPositiveTestHeader(stdout,"psVectorSort", "Free float vectors");
+    psFree(in);
+    psFree(out);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psVectorSort", "Free float vectors", true);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/collections/tst_psVectorSort_02.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psVectorSort_02.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psVectorSort_02.c	(revision 2163)
@@ -0,0 +1,73 @@
+/** @file  tst_psVectorSort_02.c
+ *
+ *  @brief Test driver for psVectorSort functions
+ *
+ *  This test driver contains the following tests for psVectorSort test point 2:
+ *     A)  Create vectors
+ *     B)  Sort integer vector of indices based on pre-sort order of floating point vector
+ *     C)  Free vectors
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.3 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-08-06 22:34:05 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+    psVector *in = NULL;
+    psVector *out = NULL;
+
+
+    // Test A - Create float vectors
+    printPositiveTestHeader(stdout,"psVectorSortIndex", "Create vectors");
+    in = psVectorAlloc(5, PS_TYPE_F32);
+    in->n = 5;
+    in->data.F32[0] = 7.0f;
+    in->data.F32[1] = 9.0f;
+    in->data.F32[2] = 3.0f;
+    in->data.F32[3] = 1.0f;
+    in->data.F32[4] = 5.0f;
+    for(int i=0; i<5; i++) {
+        printf("arr[%d] = %f\n", i, in->data.F32[i]);
+    }
+    printFooter(stdout, "psVectorSortIndex", "Create vectors", true);
+
+
+    // Test B - Sort integer vector of indices based on pre-sort order of floating point vector
+    printPositiveTestHeader(stdout,"psVectorSortIndex", "Create sorted index vector");
+    out = psVectorSortIndex(out, in);
+    for(int i=0; i<5; i++) {
+        printf("arr[%d] = %d\n", i, out->data.U32[i]);
+    }
+    printFooter(stdout, "psVectorSortIndex", "Create sorted index vector", true);
+
+    // Test D - Verify the output vector is of type psU32
+    printPositiveTestHeader(stdout,"psVectorSortIndex", "Verify output vector type");
+    if(out->type.type != PS_TYPE_U32) {
+        printf("ERROR: output vector is of type %d\n", out->type.type);
+    }
+    printFooter(stdout, "psVectorSortIndex", "Verify output vector type", true);
+
+    // Test C - Free vectors
+    printPositiveTestHeader(stdout,"psVectorSortIndex", "Free vectors");
+    psFree(in);
+    psFree(out);
+    int nLeaks = psMemCheckLeaks(0, NULL, stdout);
+    if(nLeaks) {
+        printf("ERROR: Found %d memory leaks\n", nLeaks);
+    }
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psVectorSort", "Free vectors", true);
+
+}
Index: /branches/rel3/psLib/test/collections/tst_psVectorSort_03.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psVectorSort_03.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psVectorSort_03.c	(revision 2163)
@@ -0,0 +1,84 @@
+/** @file  tst_psVectorSort_03.c
+ *
+ *  @brief Test driver for psVectorSort functions
+ *
+ *  This test driver contains the following tests for psVectorSort test point 3:
+ *     A)  Create float vectors of different sizes
+ *     B)  Attempt to sort vectors...should get errors
+ *     C)  Create float vector and double vector
+ *     D)  Attempt to sort vectors...should get errors
+ *     E)  Free float, double vectors
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.4 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-08-06 22:34:05 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+    psVector *in = NULL;
+    psVector *out = NULL;
+    psVector *in2 = NULL;
+    psVector *out2 = NULL;
+
+    // Test A - Create float vectors
+    printPositiveTestHeader(stdout,"psVectorSort", "Create float vectors of different sizes");
+    in = psVectorAlloc(5, PS_TYPE_F32);
+    in->n = 5;
+    out = psVectorAlloc(6, PS_TYPE_F32);
+    out->n = 6;
+    in->n = 5;
+    for(int i=0; i<5; i++) {
+        printf("arr[%d] = %f\n", i, in->data.F32[i]);
+    }
+    printFooter(stdout, "psVectorSort", "Create float vectors of different sizes", true);
+
+
+    // Test B - Sort input float vector and put results into output float vector
+    printNegativeTestHeader(stdout,"psVectorSort", "Sort float vector",
+                            "Input and output vector sizes are not equal", 0);
+    out = psVectorSort(out, in);
+    printFooter(stdout, "psVectorSort", "Sort float vector", true);
+
+    // Test C - Create float vector and double vector
+    printPositiveTestHeader(stdout,"psVectorSort","Create float & double vectors of same size");
+    in2 = psVectorAlloc(5, PS_TYPE_F32);
+    in2->n = 5;
+    out2 = psVectorAlloc(5, PS_TYPE_F64);
+    out2->n = 5;
+    for(int j=0; j<5; j++) {
+        printf("vec[%d] = %f\n", j, in2->data.F32[j]);
+    }
+    printFooter(stdout, "psVectorSort", "Create float and double vectors same size", true);
+
+    // Test D - Attempt to sort vectors with output of different type should create error
+    printNegativeTestHeader(stdout,"psVectorSort", "Sort F32/F64 vector",
+                            "Input and output vector different types", 0);
+    out2 = psVectorSort(out2, in2);
+    printFooter(stdout, "psVectorSort", "Sort float vector", true);
+
+    // Test C - Free float vectors
+    printPositiveTestHeader(stdout,"psVectorSort", "Free float vectors");
+    psFree(in);
+    psFree(in2);
+    psFree(out);
+    psFree(out2);
+    int nLeaks = psMemCheckLeaks(0, NULL, stdout);
+    if(nLeaks) {
+        printf("ERROR: Found %d memory leaks\n", nLeaks);
+    }
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psVectorSort", "Free float vectors", true);
+
+}
Index: /branches/rel3/psLib/test/collections/tst_psVectorSort_04.c
===================================================================
--- /branches/rel3/psLib/test/collections/tst_psVectorSort_04.c	(revision 2163)
+++ /branches/rel3/psLib/test/collections/tst_psVectorSort_04.c	(revision 2163)
@@ -0,0 +1,47 @@
+/** @file  tst_psVectorSort_04.c
+ *
+ *  @brief Test driver for psVectorSort functions
+ *
+ *  This test driver contains the following tests for psVectorSort test point 4:
+ *     A)  Attempt to sort with null input vector
+ *     B)  Free vectors
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.3 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-08-06 22:34:05 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+    psVector *badIn = NULL;
+    psVector *goodOut = psVectorAlloc(5, PS_TYPE_F32);
+
+    // Test A - Attempt to sort with null input vector
+    printNegativeTestHeader(stdout,"psVectorSort", "Attempt to sort with null input vector",
+                            "Null input vector", 0);
+    goodOut = psVectorSort(goodOut, badIn);
+    printFooter(stdout, "psVectorSort", "Attempt to sort with null input vector", true);
+
+    // Test B - Free vectors
+    printPositiveTestHeader(stdout, "psVectorSort", "Free vectors");
+    psFree(goodOut);
+    int nLeaks = psMemCheckLeaks(0, NULL, stdout);
+    if(nLeaks) {
+        printf("ERROR: Found %d memory blocks\n", nLeaks);
+    }
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psVectorSort", "Free arays", true);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/collections/verified/tst_psArray.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psArray.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psArray.stdout	(revision 2163)
@@ -0,0 +1,70 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psArray.c                                              *
+*            TestPoint: psArray{Create void pointer array}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psArray{Create void pointer array} | tst_psArray.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psArray.c                                              *
+*            TestPoint: psArray{Add data to void pointer array}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ts[0].x = 0 ts[0].y = 0.00
+ts[1].x = 10 ts[1].y = 10.10
+ts[2].x = 20 ts[2].y = 20.20
+ts[3].x = 30 ts[3].y = 30.30
+ts[4].x = 40 ts[4].y = 40.40
+array size = 5
+array population = 5
+
+---> TESTPOINT PASSED (psArray{Add data to void pointer array} | tst_psArray.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psArray.c                                              *
+*            TestPoint: psArray{Reallocate void pointer array bigger}              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Adding more elements to void pointer array...
+ts[0].x = 0 ts[0].y = 0.00
+ts[1].x = 10 ts[1].y = 10.10
+ts[2].x = 20 ts[2].y = 20.20
+ts[3].x = 30 ts[3].y = 30.30
+ts[4].x = 40 ts[4].y = 40.40
+ts[5].x = 50 ts[5].y = 50.50
+ts[6].x = 60 ts[6].y = 60.60
+ts[7].x = 70 ts[7].y = 70.70
+ts[8].x = 80 ts[8].y = 80.80
+ts[9].x = 90 ts[9].y = 90.90
+array size = 10
+array population = 10
+
+---> TESTPOINT PASSED (psArray{Reallocate void pointer array bigger} | tst_psArray.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psArray.c                                              *
+*            TestPoint: psArray{Reallocate void pointer array smaller}             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ts[0].x = 0 ts[0].y = 0.00
+ts[1].x = 10 ts[1].y = 10.10
+ts[2].x = 20 ts[2].y = 20.20
+array size = 3
+array population = 3
+
+---> TESTPOINT PASSED (psArray{Reallocate integer void pointer smaller} | tst_psArray.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psArray.c                                              *
+*            TestPoint: psArray{Free void pointer array}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psArray{Free void pointer array} | tst_psArray.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psBitSet.stderr
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psBitSet.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psBitSet.stderr	(revision 2163)
@@ -0,0 +1,147 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet.c                                             *
+*            TestPoint: psBitSet{psBitSetAlloc}                                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Creating psBitSet with 24 bits...
+Creating psBitSet with 25 bits...
+<DATE><TIME>|<HOST>|I|testBitSet01a
+    Following is an error.
+<DATE><TIME>|<HOST>|E|psLib.collections.psBitSetAlloc
+    The number of bit in a psBitSet (-4) must be greater than zero.
+
+---> TESTPOINT PASSED (psBitSet{psBitSetAlloc} | tst_psBitSet.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet.c                                             *
+*            TestPoint: psBitSet{psBitSetSet/psBitSetClear}                        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Setting first bit...
+Setting third bit...
+Setting last bit...
+100000000000000000000101
+
+Clearing first bit...
+Clearing third bit...
+Clearing last bit...
+000000000000000000000000
+
+<DATE><TIME>|<HOST>|I|testBitSet01b
+    Following should be an error
+<DATE><TIME>|<HOST>|E|psLib.collections.psBitSetSet
+    The specified bit position (-4) is invalid.  Position must be between 0 and 23.
+<DATE><TIME>|<HOST>|I|testBitSet01b
+    Following should be an error
+<DATE><TIME>|<HOST>|E|psLib.collections.psBitSetSet
+    The specified bit position (200) is invalid.  Position must be between 0 and 23.
+<DATE><TIME>|<HOST>|I|testBitSet01b
+    Following should be an error
+<DATE><TIME>|<HOST>|E|psLib.collections.psBitSetSet
+    Can not operate on a NULL psBitSet.
+
+---> TESTPOINT PASSED (psBitSet{psBitSetSet/psBitSetClear} | tst_psBitSet.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet.c                                             *
+*            TestPoint: psBitSet{psBitSetTest}                                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Setting first bit...
+Setting third bit...
+Setting last bit...
+<DATE><TIME>|<HOST>|I|testBitSet01c
+    Following should be an error
+<DATE><TIME>|<HOST>|E|psLib.collections.psBitSetTest
+    The specified bit position (-4) is invalid.  Position must be between 0 and 23.
+<DATE><TIME>|<HOST>|I|testBitSet01c
+    Following should be an error
+<DATE><TIME>|<HOST>|E|psLib.collections.psBitSetTest
+    The specified bit position (200) is invalid.  Position must be between 0 and 23.
+<DATE><TIME>|<HOST>|I|testBitSet01c
+    Following should be an error
+<DATE><TIME>|<HOST>|E|psLib.collections.psBitSetTest
+    Can not operate on a NULL psBitSet.
+
+---> TESTPOINT PASSED (psBitSet{psBitSetTest} | tst_psBitSet.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet.c                                             *
+*            TestPoint: psBitSet{psBitSetOp}                                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testBitSet06
+    Following should be an error
+<DATE><TIME>|<HOST>|E|psLib.collections.psBitSetOp
+    The psBitSet operand must be the same size.
+<DATE><TIME>|<HOST>|I|testBitSet06
+    Following is an error.
+<DATE><TIME>|<HOST>|E|psLib.collections.psBitSetOp
+    Specified operator, FOO, is invalid.  Valid operators are AND, OR, and XOR.
+<DATE><TIME>|<HOST>|I|testBitSet06
+    Following is an error.
+<DATE><TIME>|<HOST>|E|psLib.collections.psBitSetOp
+    Specified operator, FOO, is invalid.  Valid operators are AND, OR, and XOR.
+
+---> TESTPOINT PASSED (psBitSet{psBitSetOp} | tst_psBitSet.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet.c                                             *
+*            TestPoint: psBitSet{psBitSetOp AND Operator}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+psBitSetOp input is 001100110011001100110011, 010101010101010101010101.  Truth is 000100010001000100010001.
+<DATE><TIME>|<HOST>|I|testBitSet02
+    Perform binary AND with psBitSets
+<DATE><TIME>|<HOST>|I|testBitSet02
+    Perform binary AND and auto allocate output
+
+---> TESTPOINT PASSED (psBitSet{psBitSetOp AND Operator} | tst_psBitSet.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet.c                                             *
+*            TestPoint: psBitSet{psBitSetOp OR Operator}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+psBitSetOp input is 110011001100110011001100, 101010101010101010101010.  Truth is 111011101110111011101110.
+<DATE><TIME>|<HOST>|I|testBitSet03
+    Perform binary OR with psBitSets
+<DATE><TIME>|<HOST>|I|testBitSet03
+    Perform binary OR and auto allocate output
+
+---> TESTPOINT PASSED (psBitSet{psBitSetOp OR Operator} | tst_psBitSet.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet.c                                             *
+*            TestPoint: psBitSet{psBitSetOp XOR Operator}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+psBitSetOp input is 110011001100110011001100, 101010101010101010101010.  Truth is 011001100110011001100110.
+<DATE><TIME>|<HOST>|I|testBitSet04
+    Perform binary XOR with psBitSets
+<DATE><TIME>|<HOST>|I|testBitSet04
+    Perform binary XOR and auto allocate output
+
+---> TESTPOINT PASSED (psBitSet{psBitSetOp XOR Operator} | tst_psBitSet.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psBitSet.c                                             *
+*            TestPoint: psBitSet{psBitSetNot}                                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+psBitSetOp input is 101010101010101010101010.  Truth is 010101010101010101010101.
+<DATE><TIME>|<HOST>|I|testBitSet05
+    Perform binary NOT with psBitSets
+<DATE><TIME>|<HOST>|I|testBitSet05
+    Perform binary NOT and auto allocate output
+
+---> TESTPOINT PASSED (psBitSet{psBitSetNot} | tst_psBitSet.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psHash00.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psHash00.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psHash00.stdout	(revision 2163)
@@ -0,0 +1,9 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash00.c                                             *
+*            TestPoint: psHash functions{psHashAlloc()}                            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHash functions{psHashAlloc()} | tst_psHash00.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psHash01.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psHash01.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psHash01.stdout	(revision 2163)
@@ -0,0 +1,9 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash01.c                                             *
+*            TestPoint: psHash functions{psHashFree()}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHash functions{psHashFree()} | tst_psHash01.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psHash03.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psHash03.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psHash03.stdout	(revision 2163)
@@ -0,0 +1,9 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash03.c                                             *
+*            TestPoint: psHash functions{psHashRemove()}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHash functions{psHashRemove()} | tst_psHash03.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psHash04.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psHash04.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psHash04.stdout	(revision 2163)
@@ -0,0 +1,13 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash04.c                                             *
+*            TestPoint: psHash functions{psHashKeyList()}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Linked List Entries: ENTRY03
+Linked List Entries: ENTRY02
+Linked List Entries: ENTRY01
+Linked List Entries: ENTRY00
+
+---> TESTPOINT PASSED (psHash functions{psHashKeyList()} | tst_psHash04.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psList.stderr
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psList.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psList.stderr	(revision 2163)
@@ -0,0 +1,118 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psList.c                                               *
+*            TestPoint: psList{psListAlloc}                                        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testListAlloc
+    psListAlloc shall create a psList with either 0 or 1 element.
+
+---> TESTPOINT PASSED (psList{psListAlloc} | tst_psList.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psList.c                                               *
+*            TestPoint: psList{psListAdd}                                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testListAdd
+    psListAdd shall add an element to list
+<DATE><TIME>|<HOST>|I|testListAdd
+    Following should error with invalid insert location
+<DATE><TIME>|<HOST>|W|psListAdd
+    The given insert location (-10) for psListAdd is invalid.
+<DATE><TIME>|<HOST>|I|testListAdd
+    Following should be a warning.
+<DATE><TIME>|<HOST>|W|psListAdd
+    Invalid index 9 (only 6 elements in psList); assuming tail.
+
+---> TESTPOINT PASSED (psList{psListAdd} | tst_psList.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psList.c                                               *
+*            TestPoint: psList{psListGet}                                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testListGet
+    Following should be an error
+<DATE><TIME>|<HOST>|E|listSetIterator
+    Unexpected null pointer for psList parameter (psList.c:<LINENO>).
+
+---> TESTPOINT PASSED (psList{psListGet} | tst_psList.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psList.c                                               *
+*            TestPoint: psList{psListRemove}                                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testListRemove
+    Following should be an error
+<DATE><TIME>|<HOST>|E|psListRemove
+    list parameter found to be NULL in psListRemove
+<DATE><TIME>|<HOST>|I|testListRemove
+    Next message should be an error
+<DATE><TIME>|<HOST>|E|psListRemove
+    Couldn't position to given index (-4) to remove element from list.
+<DATE><TIME>|<HOST>|I|testListRemove
+    Next message should be an error
+<DATE><TIME>|<HOST>|E|psListRemove
+    Couldn't position to given index (-2) to remove element from list.
+<DATE><TIME>|<HOST>|I|testListRemove
+    Next message should be an error
+<DATE><TIME>|<HOST>|E|psListRemove
+    Failed to find item in given psList.
+<DATE><TIME>|<HOST>|I|testListRemove
+    Next message should be an error
+<DATE><TIME>|<HOST>|E|psListRemove
+    Failed to find item in given psList.
+
+---> TESTPOINT PASSED (psList{psListRemove} | tst_psList.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psList.c                                               *
+*            TestPoint: psList{psListConvert}                                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psList{psListConvert} | tst_psList.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psList.c                                               *
+*            TestPoint: psList{psListIterator}                                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testListIterator
+     psListSetIterator/psListGetNext/psListGetPrev shall move the list cursor to the specified location
+<DATE><TIME>|<HOST>|I|testListIterator
+    Following should error with 'Unexpected null pointer'
+<DATE><TIME>|<HOST>|E|listSetIterator
+    Unexpected null pointer for psList parameter (psList.c:<LINENO>).
+<DATE><TIME>|<HOST>|I|testListIterator
+    Following should error with 'Can't move to an unknown position.'
+<DATE><TIME>|<HOST>|E|listSetIterator
+    Can't move to an unknown position.  Not moving the iterator position.
+
+---> TESTPOINT PASSED (psList{psListIterator} | tst_psList.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psList.c                                               *
+*            TestPoint: psList{psListFree}                                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psList{psListFree} | tst_psList.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psList.c                                               *
+*            TestPoint: psList{psListSort}                                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psList{psListSort} | tst_psList.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psSort_01.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psSort_01.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psSort_01.stdout	(revision 2163)
@@ -0,0 +1,57 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_01.c                                            *
+*            TestPoint: psSort{Create float vectors}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+vec[0] = 7.000000
+vec[1] = 9.000000
+vec[2] = 3.000000
+vec[3] = 1.000000
+vec[4] = 5.000000
+vec[5] = 5.000000
+vec[6] = -20.000000
+
+---> TESTPOINT PASSED (psSort{Create float vectors} | tst_psSort_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_01.c                                            *
+*            TestPoint: psSort{Sort float vector}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+vec[0] = -20.000000
+vec[1] = 1.000000
+vec[2] = 3.000000
+vec[3] = 5.000000
+vec[4] = 5.000000
+vec[5] = 7.000000
+vec[6] = 9.000000
+
+---> TESTPOINT PASSED (psSort{Sort float vector} | tst_psSort_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_01.c                                            *
+*            TestPoint: psSort{Sort input float vector into itself}                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+vec[0] = -20.000000
+vec[1] = 1.000000
+vec[2] = 3.000000
+vec[3] = 5.000000
+vec[4] = 5.000000
+vec[5] = 7.000000
+vec[6] = 9.000000
+
+---> TESTPOINT PASSED (psSort{Sort input float vector into itself} | tst_psSort_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_01.c                                            *
+*            TestPoint: psSort{Free float vectors}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psSort{Free float vectors} | tst_psSort_01.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psSort_02.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psSort_02.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psSort_02.stdout	(revision 2163)
@@ -0,0 +1,37 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_02.c                                            *
+*            TestPoint: psSort{Create vectors}                                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+arr[0] = 7.000000
+arr[1] = 9.000000
+arr[2] = 3.000000
+arr[3] = 1.000000
+arr[4] = 5.000000
+
+---> TESTPOINT PASSED (psSort{Create vectors} | tst_psSort_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_02.c                                            *
+*            TestPoint: psSort{Create sorted index vector}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+arr[0] = 3
+arr[1] = 2
+arr[2] = 4
+arr[3] = 0
+arr[4] = 1
+
+---> TESTPOINT PASSED (psSort{Create sorted index vector} | tst_psSort_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_02.c                                            *
+*            TestPoint: psSort{Free vectors}                                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psSort{Free vectors} | tst_psSort_02.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psSort_03.stderr
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psSort_03.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psSort_03.stderr	(revision 2163)
@@ -0,0 +1,1 @@
+ <DATE> <TIME> |<HOST>|E|         psSort| : Line 137 - Input and output vector sizes are not equal: in=5 out=6
Index: /branches/rel3/psLib/test/collections/verified/tst_psSort_03.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psSort_03.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psSort_03.stdout	(revision 2163)
@@ -0,0 +1,34 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_03.c                                            *
+*            TestPoint: psSort{Create float vectors of different sizes}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+arr[0] = 0.000000
+arr[1] = 0.000000
+arr[2] = 0.000000
+arr[3] = 0.000000
+arr[4] = 0.000000
+
+---> TESTPOINT PASSED (psSort{Create float vectors of different sizes} | tst_psSort_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_03.c                                            *
+*            TestPoint: psSort{Sort float vector}                                  *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Input and output vector sizes are not equal                *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psSort{Sort float vector} | tst_psSort_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_03.c                                            *
+*            TestPoint: psSort{Free float vectors}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psSort{Free float vectors} | tst_psSort_03.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psSort_04.stderr
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psSort_04.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psSort_04.stderr	(revision 2163)
@@ -0,0 +1,1 @@
+ <DATE> <TIME> |<HOST>|E|         psSort| : Line 119 - Null input vector
Index: /branches/rel3/psLib/test/collections/verified/tst_psSort_04.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psSort_04.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psSort_04.stdout	(revision 2163)
@@ -0,0 +1,20 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_04.c                                            *
+*            TestPoint: psSort{Attempt to sort with null input vector}             *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null input vector                                          *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psSort{Attempt to sort with null input vector} | tst_psSort_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psSort_04.c                                            *
+*            TestPoint: psSort{Free vectors}                                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psSort{Free arays} | tst_psSort_04.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psVector.stderr
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psVector.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psVector.stderr	(revision 2163)
@@ -0,0 +1,6 @@
+<DATE><TIME>|<HOST>|I|main
+    Following should be an error message.
+<DATE><TIME>|<HOST>|I|main
+    Following should be an error message.
+<DATE><TIME>|<HOST>|E|psLib.collections.psVectorRealloc
+    psVectorRealloc must a given a non-NULL psVector to resize.  Desired datatype unknown.
Index: /branches/rel3/psLib/test/collections/verified/tst_psVector.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psVector.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psVector.stdout	(revision 2163)
@@ -0,0 +1,92 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector.c                                             *
+*            TestPoint: psVector{Create S32 vector}                                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Vector size = 5
+Vector type = 260
+Vector dimen = 1
+
+---> TESTPOINT PASSED (psVector{Create S32 vector} | tst_psVector.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector.c                                             *
+*            TestPoint: psVector{Add data to S32 vector}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Elem 0 = 0
+Elem 1 = 10
+Elem 2 = 20
+Elem 3 = 30
+Elem 4 = 40
+Vector size = 5
+Vector population = 5
+
+---> TESTPOINT PASSED (psVector{Add data to S32 vector} | tst_psVector.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector.c                                             *
+*            TestPoint: psVector{Reallocate S32 vector bigger}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Adding more elements to S32 vector...
+Elem 5 = 50
+Elem 6 = 60
+Elem 7 = 70
+Elem 8 = 80
+Elem 9 = 90
+Vector size = 10
+Vector population = 10
+
+---> TESTPOINT PASSED (psVector{Reallocate S32 vector bigger} | tst_psVector.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector.c                                             *
+*            TestPoint: psVector{Reallocate S32 vector smaller}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Vector size = 3
+Elem 0 = 0
+Elem 1 = 10
+Elem 2 = 20
+Vector size = 3
+Vector population = 3
+
+---> TESTPOINT PASSED (psVector{Reallocate integer S32 smaller} | tst_psVector.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector.c                                             *
+*            TestPoint: psVector{Free S32 vector}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector{Free S32 vector} | tst_psVector.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector.c                                             *
+*            TestPoint: psVector{Attempt to create a S32 vector with zero size}    *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid value for nalloc                                   *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+ERROR: Return is not NULL
+
+---> TESTPOINT PASSED (psVector{Attempt to create a S32 vector with zero size} | tst_psVector.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector.c                                             *
+*            TestPoint: psVector{Attempt to realloc a null S32 vector}             *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null input vector                                          *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector{Attempt to realloc a null S32 vector} | tst_psVector.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_01.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_01.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_01.stdout	(revision 2163)
@@ -0,0 +1,57 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_01.c                                      *
+*            TestPoint: psVectorSort{Create float vectors}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+vec[0] = 7.000000
+vec[1] = 9.000000
+vec[2] = 3.000000
+vec[3] = 1.000000
+vec[4] = 5.000000
+vec[5] = 5.000000
+vec[6] = -20.000000
+
+---> TESTPOINT PASSED (psVectorSort{Create float vectors} | tst_psVectorSort_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_01.c                                      *
+*            TestPoint: psVectorSort{Sort float vector}                            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+vec[0] = -20.000000
+vec[1] = 1.000000
+vec[2] = 3.000000
+vec[3] = 5.000000
+vec[4] = 5.000000
+vec[5] = 7.000000
+vec[6] = 9.000000
+
+---> TESTPOINT PASSED (psVectorSort{Sort float vector} | tst_psVectorSort_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_01.c                                      *
+*            TestPoint: psVectorSort{Sort input float vector into itself}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+vec[0] = -20.000000
+vec[1] = 1.000000
+vec[2] = 3.000000
+vec[3] = 5.000000
+vec[4] = 5.000000
+vec[5] = 7.000000
+vec[6] = 9.000000
+
+---> TESTPOINT PASSED (psVectorSort{Sort input float vector into itself} | tst_psVectorSort_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_01.c                                      *
+*            TestPoint: psVectorSort{Free float vectors}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSort{Free float vectors} | tst_psVectorSort_01.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_02.stderr
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_02.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_02.stderr	(revision 2163)
@@ -0,0 +1,2 @@
+<DATE><TIME>|<HOST>|E|psLib.collections.psVectorSortIndex
+    Input psVector is an unsupported type (0).
Index: /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_02.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_02.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_02.stdout	(revision 2163)
@@ -0,0 +1,46 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_02.c                                      *
+*            TestPoint: psVectorSortIndex{Create vectors}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+arr[0] = 7.000000
+arr[1] = 9.000000
+arr[2] = 3.000000
+arr[3] = 1.000000
+arr[4] = 5.000000
+
+---> TESTPOINT PASSED (psVectorSortIndex{Create vectors} | tst_psVectorSort_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_02.c                                      *
+*            TestPoint: psVectorSortIndex{Create sorted index vector}              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+arr[0] = 0
+arr[1] = 0
+arr[2] = 0
+arr[3] = 0
+arr[4] = 0
+
+---> TESTPOINT PASSED (psVectorSortIndex{Create sorted index vector} | tst_psVectorSort_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_02.c                                      *
+*            TestPoint: psVectorSortIndex{Verify output vector type}               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSortIndex{Verify output vector type} | tst_psVectorSort_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_02.c                                      *
+*            TestPoint: psVectorSortIndex{Free vectors}                            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSort{Free vectors} | tst_psVectorSort_02.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_03.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_03.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_03.stdout	(revision 2163)
@@ -0,0 +1,59 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_03.c                                      *
+*            TestPoint: psVectorSort{Create float vectors of different sizes}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+arr[0] = 0.000000
+arr[1] = 0.000000
+arr[2] = 0.000000
+arr[3] = 0.000000
+arr[4] = 0.000000
+
+---> TESTPOINT PASSED (psVectorSort{Create float vectors of different sizes} | tst_psVectorSort_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_03.c                                      *
+*            TestPoint: psVectorSort{Sort float vector}                            *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Input and output vector sizes are not equal                *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSort{Sort float vector} | tst_psVectorSort_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_03.c                                      *
+*            TestPoint: psVectorSort{Create float & double vectors of same size}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+vec[0] = 0.000000
+vec[1] = 0.000000
+vec[2] = 0.000000
+vec[3] = 0.000000
+vec[4] = 0.000000
+
+---> TESTPOINT PASSED (psVectorSort{Create float and double vectors same size} | tst_psVectorSort_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_03.c                                      *
+*            TestPoint: psVectorSort{Sort F32/F64 vector}                          *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Input and output vector different types                    *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSort{Sort float vector} | tst_psVectorSort_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_03.c                                      *
+*            TestPoint: psVectorSort{Free float vectors}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSort{Free float vectors} | tst_psVectorSort_03.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_04.stderr
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_04.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_04.stderr	(revision 2163)
@@ -0,0 +1,2 @@
+<DATE><TIME>|<HOST>|E|psLib.collections.psVectorSort
+    psVectorSort can not sort a NULL psVector.
Index: /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_04.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_04.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psVectorSort_04.stdout	(revision 2163)
@@ -0,0 +1,20 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_04.c                                      *
+*            TestPoint: psVectorSort{Attempt to sort with null input vector}       *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null input vector                                          *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSort{Attempt to sort with null input vector} | tst_psVectorSort_04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorSort_04.c                                      *
+*            TestPoint: psVectorSort{Free vectors}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVectorSort{Free arays} | tst_psVectorSort_04.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psVector_01.stderr
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psVector_01.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psVector_01.stderr	(revision 2163)
@@ -0,0 +1,2 @@
+ <DATE> <TIME> |<HOST>|E|  psVectorAlloc|Invalid value for nalloc. nalloc: 0
+ <DATE> <TIME> |<HOST>|E|psVectorRealloc|Null input vector
Index: /branches/rel3/psLib/test/collections/verified/tst_psVector_01.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psVector_01.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psVector_01.stdout	(revision 2163)
@@ -0,0 +1,91 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_01.c                                          *
+*            TestPoint: psVector{Create S32 vector}                                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Vector size = 5
+Vector type = 260
+Vector dimen = 1
+
+---> TESTPOINT PASSED (psVector{Create S32 vector} | tst_psVector_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_01.c                                          *
+*            TestPoint: psVector{Add data to S32 vector}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Elem 0 = 0
+Elem 1 = 10
+Elem 2 = 20
+Elem 3 = 30
+Elem 4 = 40
+Vector size = 5
+Vector population = 5
+
+---> TESTPOINT PASSED (psVector{Add data to S32 vector} | tst_psVector_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_01.c                                          *
+*            TestPoint: psVector{Reallocate S32 vector bigger}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Adding more elements to S32 vector...
+Elem 5 = 50
+Elem 6 = 60
+Elem 7 = 70
+Elem 8 = 80
+Elem 9 = 90
+Vector size = 10
+Vector population = 10
+
+---> TESTPOINT PASSED (psVector{Reallocate S32 vector bigger} | tst_psVector_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_01.c                                          *
+*            TestPoint: psVector{Reallocate S32 vector smaller}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Vector size = 3
+Elem 0 = 0
+Elem 1 = 10
+Elem 2 = 20
+Vector size = 3
+Vector population = 3
+
+---> TESTPOINT PASSED (psVector{Reallocate integer S32 smaller} | tst_psVector_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_01.c                                          *
+*            TestPoint: psVector{Free S32 vector}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector{Free S32 vector} | tst_psVector_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_01.c                                          *
+*            TestPoint: psVector{Attempt to create a S32 vector with zero size}    *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid value for nalloc                                   *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector{Attempt to create a S32 vector with zero size} | tst_psVector_01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_01.c                                          *
+*            TestPoint: psVector{Attempt to realloc a null S32 vector}             *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null input vector                                          *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector{Attempt to realloc a null S32 vector} | tst_psVector_01.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psVector_02.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psVector_02.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psVector_02.stdout	(revision 2163)
@@ -0,0 +1,73 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_02.c                                          *
+*            TestPoint: psVector{Create void pointer vector}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Vector size = 5
+Vector type = 0
+Vector dimen = 1
+
+---> TESTPOINT PASSED (psVector{Create void pointer vector} | tst_psVector_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_02.c                                          *
+*            TestPoint: psVector{Add data to void pointer vector}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ts[0].x = 0 ts[0].y = 0.00
+ts[1].x = 10 ts[1].y = 10.10
+ts[2].x = 20 ts[2].y = 20.20
+ts[3].x = 30 ts[3].y = 30.30
+ts[4].x = 40 ts[4].y = 40.40
+Vector size = 5
+Vector population = 5
+
+---> TESTPOINT PASSED (psVector{Add data to void pointer vector} | tst_psVector_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_02.c                                          *
+*            TestPoint: psVector{Reallocate void pointer vector bigger}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Adding more elements to void pointer vector...
+ts[0].x = 0 ts[0].y = 0.00
+ts[1].x = 10 ts[1].y = 10.10
+ts[2].x = 20 ts[2].y = 20.20
+ts[3].x = 30 ts[3].y = 30.30
+ts[4].x = 40 ts[4].y = 40.40
+ts[5].x = 50 ts[5].y = 50.50
+ts[6].x = 60 ts[6].y = 60.60
+ts[7].x = 70 ts[7].y = 70.70
+ts[8].x = 80 ts[8].y = 80.80
+ts[9].x = 90 ts[9].y = 90.90
+Vector size = 10
+Vector population = 10
+
+---> TESTPOINT PASSED (psVector{Reallocate void pointer vector bigger} | tst_psVector_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_02.c                                          *
+*            TestPoint: psVector{Reallocate void pointer vector smaller}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ts[0].x = 0 ts[0].y = 0.00
+ts[1].x = 10 ts[1].y = 10.10
+ts[2].x = 20 ts[2].y = 20.20
+Vector size = 3
+Vector population = 3
+
+---> TESTPOINT PASSED (psVector{Reallocate integer void pointer smaller} | tst_psVector_02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_02.c                                          *
+*            TestPoint: psVector{Free void pointer vector}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector{Free void pointer vector} | tst_psVector_02.c)
+
Index: /branches/rel3/psLib/test/collections/verified/tst_psVector_03.stdout
===================================================================
--- /branches/rel3/psLib/test/collections/verified/tst_psVector_03.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/collections/verified/tst_psVector_03.stdout	(revision 2163)
@@ -0,0 +1,73 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_03.c                                          *
+*            TestPoint: psVector{Create void pointer vector}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Vector size = 5
+Vector type = 0
+Vector dimen = 1
+
+---> TESTPOINT PASSED (psVector{Create void pointer vector} | tst_psVector_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_03.c                                          *
+*            TestPoint: psVector{Add data to void pointer vector}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ts[0].x = 0 ts[0].y = 0.00
+ts[1].x = 10 ts[1].y = 10.10
+ts[2].x = 20 ts[2].y = 20.20
+ts[3].x = 30 ts[3].y = 30.30
+ts[4].x = 40 ts[4].y = 40.40
+Vector size = 5
+Vector population = 5
+
+---> TESTPOINT PASSED (psVector{Add data to void pointer vector} | tst_psVector_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_03.c                                          *
+*            TestPoint: psVector{Reallocate void pointer vector bigger}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Adding more elements to void pointer vector...
+ts[0].x = 0 ts[0].y = 0.00
+ts[1].x = 10 ts[1].y = 10.10
+ts[2].x = 20 ts[2].y = 20.20
+ts[3].x = 30 ts[3].y = 30.30
+ts[4].x = 40 ts[4].y = 40.40
+ts[5].x = 50 ts[5].y = 50.50
+ts[6].x = 60 ts[6].y = 60.60
+ts[7].x = 70 ts[7].y = 70.70
+ts[8].x = 80 ts[8].y = 80.80
+ts[9].x = 90 ts[9].y = 90.90
+Vector size = 10
+Vector population = 10
+
+---> TESTPOINT PASSED (psVector{Reallocate void pointer vector bigger} | tst_psVector_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_03.c                                          *
+*            TestPoint: psVector{Reallocate void pointer vector smaller}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+ts[0].x = 0 ts[0].y = 0.00
+ts[1].x = 10 ts[1].y = 10.10
+ts[2].x = 20 ts[2].y = 20.20
+Vector size = 3
+Vector population = 3
+
+---> TESTPOINT PASSED (psVector{Reallocate integer void pointer smaller} | tst_psVector_03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVector_03.c                                          *
+*            TestPoint: psVector{Free void pointer array with function callback}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector{Free void pointer array with function callback} | tst_psVector_03.c)
+
Index: /branches/rel3/psLib/test/dataManip/.cvsignore
===================================================================
--- /branches/rel3/psLib/test/dataManip/.cvsignore	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/.cvsignore	(revision 2163)
@@ -0,0 +1,52 @@
+temp
+tmpImages
+tst_psMatrix01
+tst_psStats00
+tst_psStats01
+tst_psStats02
+tst_psStats03
+tst_psStats04
+tst_psFunc00
+tst_psFunc01
+tst_psHist00
+tst_psHist01
+tst_psHist02
+tst_psImageIO
+tst_psImageStats00
+tst_psImageStats01
+tst_psImageStats02
+tst_psMatrix02
+tst_psMatrix03
+tst_psMatrix04
+tst_psMatrix05
+tst_psMatrix06
+tst_psMatrix07
+tst_psStats05
+tst_psStats06
+tst_psStats07
+tst_psStats08
+tst_psStats09
+tst_psImageFFT
+tst_psVectorFFT
+tst_psImageStats03
+tst_psMatrixVectorArithmetic01
+tst_psMatrixVectorArithmetic02
+test/dataManip/tst_psImageManip
+tst_psMatrixVectorArithmetic03
+tst_psMinimize00
+tst_psMinimize01
+tst_psMinimize02
+tst_psMinimize03
+tst_psMinimize04
+tst_psImageManip
+tst_psFunc02
+tst_psFunc03
+tst_psFunc04
+tst_psFunc05
+tst_psFunc07
+tst_psHist03
+tst_psMinimize05
+tst_psMinimize06
+tst_psMinimize04_F32
+tst_psMinimize04b
+tst_psMinimize04b_F32
Index: /branches/rel3/psLib/test/dataManip/Makefile
===================================================================
--- /branches/rel3/psLib/test/dataManip/Makefile	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/Makefile	(revision 2163)
@@ -0,0 +1,84 @@
+################################################################################
+##
+##  Makefile:   test/sysUtils
+##
+##  $Revision: 1.51 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-10-12 20:59:07 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+##
+###############################################################################
+
+ifndef prefix
+    export prefix=$(shell cd ../..;pwd)
+endif
+
+include ../../src/Makefile.Globals
+
+CFLAGS := -I../../include $(CFLAGS)
+LDFLAGS := -L../../lib -lpslib -lpstest $(LDFLAGS)
+TARGET = \
+tst_psFunc00 \
+tst_psFunc01 \
+tst_psFunc02 \
+tst_psFunc03 \
+tst_psFunc04 \
+tst_psFunc05 \
+tst_psFunc07 \
+tst_psHist00 \
+tst_psHist01 \
+tst_psHist02 \
+tst_psHist03 \
+tst_psMatrix01 \
+tst_psMatrix02 \
+tst_psMatrix03 \
+tst_psMatrix04 \
+tst_psMatrix05 \
+tst_psMatrix06 \
+tst_psMatrix07 \
+tst_psMatrixVectorArithmetic01 \
+tst_psMatrixVectorArithmetic02 \
+tst_psMatrixVectorArithmetic03 \
+tst_psMinimize04 \
+tst_psMinimize04_F32 \
+tst_psMinimize04b \
+tst_psMinimize04b_F32 \
+tst_psMinimize05 \
+tst_psMinimize06 \
+tst_psStats00 \
+tst_psStats01 \
+tst_psStats02 \
+tst_psStats03 \
+tst_psStats05 \
+tst_psStats06 \
+tst_psStats07 \
+tst_psStats08 \
+tst_psStats09 \
+tst_psVectorFFT 
+# tst_psFunc06 \
+# tst_psMinimize04b \
+
+OBJS = $(addsuffix .o,$(TARGET))
+
+all: $(TARGET)
+
+# include $(DEPENDENCIES)
+
+clean:
+	@echo "    Deleting executable and binary files for 'test/collections'"
+	$(RM) $(OBJS)
+
+distclean: clean
+	$(RM) $(TARGET)
+
+install: $(testbindir) $(testbindir)/verified $(TARGET)
+	install $(TARGET) $(testbindir)
+	install verified/*.stderr verified/*.stdout $(testbindir)/verified
+
+$(testbindir):
+	mkdir -p $(testbindir)
+
+$(testbindir)/verified:
+	mkdir -p $(testbindir)/verified
+
+
Index: /branches/rel3/psLib/test/dataManip/tst_psFunc00.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psFunc00.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psFunc00.c	(revision 2163)
@@ -0,0 +1,533 @@
+/*****************************************************************************
+    This routine must ensure that the psPolynomial structures are
+    allocated and deallocated by the psPolynomialXXXlloc() procedures.
+    It also calls the various psPolynomialXXXEval() procedures.
+ 
+    The F32 and F64 polynomials are tested for all orders (1 - 4) and for
+    both ordinary and chebyshev polynomials.
+ 
+    NOTE: This test code requries the stdout file to verify that the results
+    are good.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psFunctions.h"
+#define MISC_FLOAT_NUMBER 345.0
+#define MISC_X_VALUE 5.0
+#define MISC_INT_NUMBER 35
+#define AN 2
+#define BN 4
+#define CN 6
+#define DN 8
+int main()
+{
+    psPolynomial1D *my1DPoly = NULL;
+    psPolynomial2D *my2DPoly = NULL;
+    psPolynomial3D *my3DPoly = NULL;
+    psPolynomial4D *my4DPoly = NULL;
+    psDPolynomial1D *my1DPolyD = NULL;
+    psDPolynomial2D *my2DPolyD = NULL;
+    psDPolynomial3D *my3DPolyD = NULL;
+    psDPolynomial4D *my4DPolyD = NULL;
+    int testStatus      = true;
+    int memLeaks        = 0;
+    int a               = 0;
+    int b               = 0;
+    int c               = 0;
+    int d               = 0;
+    int currentId       = 0;
+
+    currentId       = psMemGetId();
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psPolynomial1D structure.");
+
+    my1DPoly = psPolynomial1DAlloc(AN, PS_POLYNOMIAL_ORD);
+    for (a = 0; a < AN ; a++) {
+        my1DPoly->coeff[a] = MISC_FLOAT_NUMBER;
+        my1DPoly->coeffErr[a] = MISC_FLOAT_NUMBER;
+        my1DPoly->mask[a] = MISC_INT_NUMBER;
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x) = (%f): %f\n", MISC_X_VALUE,
+           psPolynomial1DEval(MISC_X_VALUE, my1DPoly));
+
+    psFree(my1DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "Allocate/Deallocate the psPolynomial1D structure.",
+                testStatus);
+
+
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psPolynomial2D structure.");
+    my2DPoly = psPolynomial2DAlloc(AN, BN, PS_POLYNOMIAL_ORD);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            my2DPoly->coeff[a][b] = MISC_FLOAT_NUMBER;
+            my2DPoly->coeffErr[a][b] = MISC_FLOAT_NUMBER;
+            my2DPoly->mask[a][b] = MISC_INT_NUMBER;
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x, y) = (%f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           psPolynomial2DEval(MISC_X_VALUE, MISC_X_VALUE, my2DPoly));
+
+    psFree(my2DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "Allocate/Deallocate the psPolynomial2D structure.",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psPolynomial3D structure.");
+    my3DPoly = psPolynomial3DAlloc(AN, BN, CN, PS_POLYNOMIAL_ORD);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            for (c = 0; c < CN ; c++) {
+                my3DPoly->coeff[a][b][c] = MISC_FLOAT_NUMBER;
+                my3DPoly->coeffErr[a][b][c] = MISC_FLOAT_NUMBER;
+                my3DPoly->mask[a][b][c] = MISC_INT_NUMBER;
+            }
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x, y, z) = (%f, %f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           MISC_X_VALUE,
+           psPolynomial3DEval(MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, my3DPoly));
+
+    psFree(my3DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "Allocate/Deallocate the psPolynomial3D structure.",
+                testStatus);
+
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psPolynomial4D structure.");
+    my4DPoly = psPolynomial4DAlloc(AN, BN, CN, DN, PS_POLYNOMIAL_ORD);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            for (c = 0; c < CN ; c++) {
+                for (d = 0; d < DN ; d++) {
+                    my4DPoly->coeff[a][b][c][d] = MISC_FLOAT_NUMBER;
+                    my4DPoly->coeffErr[a][b][c][d] = MISC_FLOAT_NUMBER;
+                    my4DPoly->mask[a][b][c][d] = MISC_INT_NUMBER;
+                }
+            }
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (w, x, y, z) = (%f, %f, %f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           MISC_X_VALUE, MISC_X_VALUE,
+           psPolynomial4DEval(MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, my4DPoly));
+
+    psFree(my4DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "Allocate/Deallocate the psPolynomial4D structure.",
+                testStatus);
+
+
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psDPolynomial1D structure.");
+
+    my1DPolyD = psDPolynomial1DAlloc(AN, PS_POLYNOMIAL_ORD);
+    for (a = 0; a < AN ; a++) {
+        my1DPolyD->coeff[a] = MISC_FLOAT_NUMBER;
+        my1DPolyD->coeffErr[a] = MISC_FLOAT_NUMBER;
+        my1DPolyD->mask[a] = MISC_INT_NUMBER;
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x) = (%f): %f\n", MISC_X_VALUE,
+           psDPolynomial1DEval(MISC_X_VALUE, my1DPolyD));
+
+    psFree(my1DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "Allocate/Deallocate the psDPolynomial1D structure.",
+                testStatus);
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psDPolynomial2D structure.");
+    my2DPolyD = psDPolynomial2DAlloc(AN, BN, PS_POLYNOMIAL_ORD);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            my2DPolyD->coeff[a][b] = MISC_FLOAT_NUMBER;
+            my2DPolyD->coeffErr[a][b] = MISC_FLOAT_NUMBER;
+            my2DPolyD->mask[a][b] = MISC_INT_NUMBER;
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x, y) = (%f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           psDPolynomial2DEval(MISC_X_VALUE, MISC_X_VALUE, my2DPolyD));
+
+    psFree(my2DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "Allocate/Deallocate the psDPolynomial2D structure.",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psDPolynomial3D structure.");
+    my3DPolyD = psDPolynomial3DAlloc(AN, BN, CN, PS_POLYNOMIAL_ORD);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            for (c = 0; c < CN ; c++) {
+                my3DPolyD->coeff[a][b][c] = MISC_FLOAT_NUMBER;
+                my3DPolyD->coeffErr[a][b][c] = MISC_FLOAT_NUMBER;
+                my3DPolyD->mask[a][b][c] = MISC_INT_NUMBER;
+            }
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x, y, z) = (%f, %f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           MISC_X_VALUE,
+           psDPolynomial3DEval(MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, my3DPolyD));
+
+    psFree(my3DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "Allocate/Deallocate the psDPolynomial3D structure.",
+                testStatus);
+
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psDPolynomial4D structure.");
+    my4DPolyD = psDPolynomial4DAlloc(AN, BN, CN, DN, PS_POLYNOMIAL_ORD);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            for (c = 0; c < CN ; c++) {
+                for (d = 0; d < DN ; d++) {
+                    my4DPolyD->coeff[a][b][c][d] = MISC_FLOAT_NUMBER;
+                    my4DPolyD->coeffErr[a][b][c][d] = MISC_FLOAT_NUMBER;
+                    my4DPolyD->mask[a][b][c][d] = MISC_INT_NUMBER;
+                }
+            }
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (w, x, y, z) = (%f, %f, %f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           MISC_X_VALUE, MISC_X_VALUE,
+           psDPolynomial4DEval(MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, my4DPolyD));
+
+    psFree(my4DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "Allocate/Deallocate the psDPolynomial4D structure.",
+                testStatus);
+
+
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psPolynomial1D structure (CHEBYSHEV).");
+
+    my1DPoly = psPolynomial1DAlloc(AN, PS_POLYNOMIAL_CHEB);
+    for (a = 0; a < AN ; a++) {
+        my1DPoly->coeff[a] = MISC_FLOAT_NUMBER;
+        my1DPoly->coeffErr[a] = MISC_FLOAT_NUMBER;
+        my1DPoly->mask[a] = MISC_INT_NUMBER;
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x) = (%f): %f\n", MISC_X_VALUE,
+           psPolynomial1DEval(MISC_X_VALUE, my1DPoly));
+
+    psFree(my1DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "Allocate/Deallocate the psPolynomial1D structure (CHEBYSHEV).",
+                testStatus);
+
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psPolynomial2D structure (CHEBYSHEV).");
+    my2DPoly = psPolynomial2DAlloc(AN, BN, PS_POLYNOMIAL_CHEB);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            my2DPoly->coeff[a][b] = MISC_FLOAT_NUMBER;
+            my2DPoly->coeffErr[a][b] = MISC_FLOAT_NUMBER;
+            my2DPoly->mask[a][b] = MISC_INT_NUMBER;
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x, y) = (%f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           psPolynomial2DEval(MISC_X_VALUE, MISC_X_VALUE, my2DPoly));
+
+    psFree(my2DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "Allocate/Deallocate the psPolynomial2D structure (CHEBYSHEV).",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psPolynomial3D structure (CHEBYSHEV).");
+    my3DPoly = psPolynomial3DAlloc(AN, BN, CN, PS_POLYNOMIAL_CHEB);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            for (c = 0; c < CN ; c++) {
+                my3DPoly->coeff[a][b][c] = MISC_FLOAT_NUMBER;
+                my3DPoly->coeffErr[a][b][c] = MISC_FLOAT_NUMBER;
+                my3DPoly->mask[a][b][c] = MISC_INT_NUMBER;
+            }
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x, y, z) = (%f, %f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           MISC_X_VALUE,
+           psPolynomial3DEval(MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, my3DPoly));
+
+    psFree(my3DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "Allocate/Deallocate the psPolynomial3D structure (CHEBYSHEV).",
+                testStatus);
+
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psPolynomial4D structure (CHEBYSHEV).");
+    my4DPoly = psPolynomial4DAlloc(AN, BN, CN, DN, PS_POLYNOMIAL_CHEB);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            for (c = 0; c < CN ; c++) {
+                for (d = 0; d < DN ; d++) {
+                    my4DPoly->coeff[a][b][c][d] = MISC_FLOAT_NUMBER;
+                    my4DPoly->coeffErr[a][b][c][d] = MISC_FLOAT_NUMBER;
+                    my4DPoly->mask[a][b][c][d] = MISC_INT_NUMBER;
+                }
+            }
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (w, x, y, z) = (%f, %f, %f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           MISC_X_VALUE, MISC_X_VALUE,
+           psPolynomial4DEval(MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, my4DPoly));
+
+    psFree(my4DPoly);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "Allocate/Deallocate the psPolynomial4D structure (CHEBYSHEV).",
+                testStatus);
+
+
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psDPolynomial1D structure (CHEBYSHEV).");
+
+    my1DPolyD = psDPolynomial1DAlloc(AN, PS_POLYNOMIAL_CHEB);
+    for (a = 0; a < AN ; a++) {
+        my1DPolyD->coeff[a] = MISC_FLOAT_NUMBER;
+        my1DPolyD->coeffErr[a] = MISC_FLOAT_NUMBER;
+        my1DPolyD->mask[a] = MISC_INT_NUMBER;
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x) = (%f): %f\n", MISC_X_VALUE,
+           psDPolynomial1DEval(MISC_X_VALUE, my1DPolyD));
+
+    psFree(my1DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "Allocate/Deallocate the psDPolynomial1D structure (CHEBYSHEV).",
+                testStatus);
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psDPolynomial2D structure (CHEBYSHEV).");
+    my2DPolyD = psDPolynomial2DAlloc(AN, BN, PS_POLYNOMIAL_CHEB);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            my2DPolyD->coeff[a][b] = MISC_FLOAT_NUMBER;
+            my2DPolyD->coeffErr[a][b] = MISC_FLOAT_NUMBER;
+            my2DPolyD->mask[a][b] = MISC_INT_NUMBER;
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x, y) = (%f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           psDPolynomial2DEval(MISC_X_VALUE, MISC_X_VALUE, my2DPolyD));
+
+    psFree(my2DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "Allocate/Deallocate the psDPolynomial2D structure (CHEBYSHEV).",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psDPolynomial3D structure (CHEBYSHEV).");
+    my3DPolyD = psDPolynomial3DAlloc(AN, BN, CN, PS_POLYNOMIAL_CHEB);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            for (c = 0; c < CN ; c++) {
+                my3DPolyD->coeff[a][b][c] = MISC_FLOAT_NUMBER;
+                my3DPolyD->coeffErr[a][b][c] = MISC_FLOAT_NUMBER;
+                my3DPolyD->mask[a][b][c] = MISC_INT_NUMBER;
+            }
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (x, y, z) = (%f, %f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           MISC_X_VALUE,
+           psDPolynomial3DEval(MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, my3DPolyD));
+
+    psFree(my3DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "Allocate/Deallocate the psDPolynomial3D structure (CHEBYSHEV).",
+                testStatus);
+
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "Allocate/Deallocate the psDPolynomial4D structure (CHEBYSHEV).");
+    my4DPolyD = psDPolynomial4DAlloc(AN, BN, CN, DN, PS_POLYNOMIAL_CHEB);
+    for (a = 0; a < AN ; a++) {
+        for (b = 0; b < BN ; b++) {
+            for (c = 0; c < CN ; c++) {
+                for (d = 0; d < DN ; d++) {
+                    my4DPolyD->coeff[a][b][c][d] = MISC_FLOAT_NUMBER;
+                    my4DPolyD->coeffErr[a][b][c][d] = MISC_FLOAT_NUMBER;
+                    my4DPolyD->mask[a][b][c][d] = MISC_INT_NUMBER;
+                }
+            }
+        }
+    }
+    psMemCheckCorruption(1);
+
+    printf("At (w, x, y, z) = (%f, %f, %f, %f): %f\n", MISC_X_VALUE, MISC_X_VALUE,
+           MISC_X_VALUE, MISC_X_VALUE,
+           psDPolynomial4DEval(MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, MISC_X_VALUE, my4DPolyD));
+
+    psFree(my4DPolyD);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psFunctions functions",
+                "Allocate/Deallocate the psDPolynomial4D structure (CHEBYSHEV).",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psFunc01.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psFunc01.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psFunc01.c	(revision 2163)
@@ -0,0 +1,76 @@
+/*****************************************************************************
+    This routine must ensure that the psGaussian() shall evaluate a
+    specified Gaussian at some X.
+ 
+    It also tests the psGaussianDev() procedure.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psFunctions.h"
+#define MY_MEAN 30.0
+#define MY_STDEV 2.0
+#define N 30
+int main()
+{
+    int testStatus = true;
+    float x = 0.0;
+    int  memLeaks;
+    int  currentId = psMemGetId();
+    psVector *myGaussData = NULL;
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "psGaussian()");
+
+
+    for (x = 0.0 ; x < (MY_MEAN * 2.0) ; x+= 1.0) {
+        printf("normal psGaussian(%f) is %f\n", x, psGaussian(x, MY_MEAN, MY_STDEV, true));
+        x = x + 1.0;
+    }
+
+    for (x = 0.0 ; x < (MY_MEAN * 2.0) ; x+= 1.0) {
+        printf("NON-normal psGaussian(%f) is %f\n", x, psGaussian(x, MY_MEAN, MY_STDEV, false));
+        x = x + 1.0;
+    }
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psGaussian()",
+                testStatus);
+
+
+    printPositiveTestHeader(stdout,
+                            "psFunctions functions",
+                            "psGaussianDev()");
+
+    myGaussData = psGaussianDev(MY_MEAN, MY_STDEV, N);
+    for (int i = 0; i < N ; i++) {
+        printf("Gaussian Deviate [%d] is %f\n", i, myGaussData->data.F32[i]);
+    }
+
+    if ( myGaussData->type.type != PS_TYPE_F32) {
+        psAbort(__func__,"psGaussianDev did not return a vector of type F32");
+    }
+
+    psFree(myGaussData);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psGaussianDev()",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psFunc02.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psFunc02.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psFunc02.c	(revision 2163)
@@ -0,0 +1,293 @@
+/*****************************************************************************
+    This routine must ensure that the psSpline1DAlloc() function properly
+    allocates the spline data structure.  It allocates both linear and cubic
+    splines with a variety of min/max ranges.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psFunctions.h"
+
+#define N 4
+#define LINEAR 1
+#define CUBIC 3
+
+int main()
+{
+    int testStatus = true;
+    int memLeaks=0;
+    int i;
+    int  currentId = psMemGetId();
+    psSpline1D *tmpSpline;
+
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAlloc(): linear, normal");
+
+    tmpSpline = psSpline1DAlloc(N, LINEAR, 1.0, 10.0);
+    if (tmpSpline == NULL) {
+        printf("ERROR: Could not allocate psSpline1D data structure\n");
+        testStatus = false;
+    }
+    if (tmpSpline->spline == NULL) {
+        printf("ERROR: Could not allocate psSpline1D->spline data structure\n");
+        testStatus = false;
+    }
+
+    if (tmpSpline->n != N) {
+        printf("ERROR: spline->n set incorrectly (%d)\n", tmpSpline->n);
+        testStatus = false;
+    }
+
+    for (i=0;i<N;i++) {
+        if (tmpSpline->spline[i] == NULL) {
+            printf("ERROR: Could not allocate spline %d\n", i);
+            testStatus = false;
+        }
+        if ((tmpSpline->spline[i])->n != LINEAR+1) {
+            printf("ERROR: Spline created with order %d\n", (tmpSpline->spline[i])->n);
+            testStatus = false;
+        }
+    }
+
+    if (tmpSpline->domains == NULL) {
+        printf("ERROR: Could not allocate psSpline1D->domains data structure\n");
+        testStatus = false;
+    }
+
+    for (i=0;i<N+1;i++) {
+        printf("psSpline1D->domains[%d] is %f\n", i, tmpSpline->domains[i]);
+    }
+
+    p_psSpline1DFree(tmpSpline);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAlloc(): linear, normal",
+                testStatus);
+
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAlloc(): linear, min/max are equal");
+
+    tmpSpline = psSpline1DAlloc(N, LINEAR, 1.0, 1.0);
+
+    if (tmpSpline != NULL) {
+        printf("ERROR: allocated psSpline1D data structure when min==max\n");
+        testStatus = false;
+    }
+
+    p_psSpline1DFree(tmpSpline);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAlloc(): linear, min/max are equal",
+                testStatus);
+
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAlloc(): linear, min > max.");
+
+    tmpSpline = psSpline1DAlloc(N, LINEAR, 1.0, -1.0);
+    if (tmpSpline == NULL) {
+        printf("ERROR: Could not allocate psSpline1D data structure\n");
+        testStatus = false;
+    }
+    if (tmpSpline->spline == NULL) {
+        printf("ERROR: Could not allocate psSpline1D->spline data structure\n");
+        testStatus = false;
+    }
+
+    if (tmpSpline->n != N) {
+        printf("ERROR: spline->n set incorrectly (%d)\n", tmpSpline->n);
+        testStatus = false;
+    }
+
+    for (i=0;i<N;i++) {
+        if (tmpSpline->spline[i] == NULL) {
+            printf("ERROR: Could not allocate spline %d\n", i);
+            testStatus = false;
+        }
+        if ((tmpSpline->spline[i])->n != LINEAR+1) {
+            printf("ERROR: Spline created with order %d\n", (tmpSpline->spline[i])->n);
+            testStatus = false;
+        }
+    }
+
+    if (tmpSpline->domains == NULL) {
+        printf("ERROR: Could not allocate psSpline1D->domains data structure\n");
+        testStatus = false;
+    }
+
+    for (i=0;i<N+1;i++) {
+        printf("psSpline1D->domains[%d] is %f\n", i, tmpSpline->domains[i]);
+    }
+
+    p_psSpline1DFree(tmpSpline);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAlloc(): linear, min > max.",
+                testStatus);
+
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAlloc(), cubic, normal");
+
+    tmpSpline = psSpline1DAlloc(N, CUBIC, 1.0, 10.0);
+    if (tmpSpline == NULL) {
+        printf("ERROR: Could not allocate psSpline1D data structure\n");
+        testStatus = false;
+    }
+    if (tmpSpline->spline == NULL) {
+        printf("ERROR: Could not allocate psSpline1D->spline data structure\n");
+        testStatus = false;
+    }
+
+    if (tmpSpline->n != N) {
+        printf("ERROR: spline->n set incorrectly (%d)\n", tmpSpline->n);
+        testStatus = false;
+    }
+
+    for (i=0;i<N;i++) {
+        if (tmpSpline->spline[i] == NULL) {
+            printf("ERROR: Could not allocate spline %d\n", i);
+            testStatus = false;
+        }
+        if ((tmpSpline->spline[i])->n != CUBIC+1) {
+            printf("ERROR: Spline created with order %d\n", (tmpSpline->spline[i])->n);
+            testStatus = false;
+        }
+    }
+
+    if (tmpSpline->domains == NULL) {
+        printf("ERROR: Could not allocate psSpline1D->domains data structure\n");
+        testStatus = false;
+    }
+
+    for (i=0;i<N+1;i++) {
+        printf("psSpline1D->domains[%d] is %f\n", i, tmpSpline->domains[i]);
+    }
+
+    p_psSpline1DFree(tmpSpline);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAlloc(): cubic, normal",
+                testStatus);
+
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAlloc(): cubic, min/max are equal");
+
+    tmpSpline = psSpline1DAlloc(N, CUBIC, 1.0, 1.0);
+
+    if (tmpSpline != NULL) {
+        printf("ERROR: allocated psSpline1D data structure when min==max\n");
+        testStatus = false;
+    }
+
+    p_psSpline1DFree(tmpSpline);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAlloc(): cubic, min/max are equal",
+                testStatus);
+
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAlloc(): cubic, min > max.");
+
+    tmpSpline = psSpline1DAlloc(N, CUBIC, 1.0, -1.0);
+    if (tmpSpline == NULL) {
+        printf("ERROR: Could not allocate psSpline1D data structure\n");
+        testStatus = false;
+    }
+    if (tmpSpline->spline == NULL) {
+        printf("ERROR: Could not allocate psSpline1D->spline data structure\n");
+        testStatus = false;
+    }
+
+    if (tmpSpline->n != N) {
+        printf("ERROR: spline->n set incorrectly (%d)\n", tmpSpline->n);
+        testStatus = false;
+    }
+
+    for (i=0;i<N;i++) {
+        if (tmpSpline->spline[i] == NULL) {
+            printf("ERROR: Could not allocate spline %d\n", i);
+            testStatus = false;
+        }
+        if ((tmpSpline->spline[i])->n != CUBIC+1) {
+            printf("ERROR: Spline created with order %d\n", (tmpSpline->spline[i])->n);
+            testStatus = false;
+        }
+    }
+
+    if (tmpSpline->domains == NULL) {
+        printf("ERROR: Could not allocate psSpline1D->domains data structure\n");
+        testStatus = false;
+    }
+
+    for (i=0;i<N+1;i++) {
+        printf("psSpline1D->domains[%d] is %f\n", i, tmpSpline->domains[i]);
+    }
+
+    p_psSpline1DFree(tmpSpline);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAlloc(): cubic, min > max.",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psFunc03.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psFunc03.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psFunc03.c	(revision 2163)
@@ -0,0 +1,148 @@
+/*****************************************************************************
+    This routine must ensure that the psSpline1DAllocGeneric() function properly
+    allocates the spline data structure.
+ 
+    XXX: test bounds?
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psFunctions.h"
+
+#define N 10
+#define LINEAR 1
+#define CUBIC 3
+
+int main()
+{
+    int testStatus = true;
+    int memLeaks=0;
+    int i;
+    int  currentId = psMemGetId();
+    psSpline1D *tmpSpline;
+    psVector *bounds;
+
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAllocGeneric(): linear");
+    bounds = psVectorAlloc(N+1, PS_TYPE_F32);
+    for (i=0;i<N+1;i++) {
+        bounds->data.F32[i] = (float) (3 * i);
+    }
+
+    tmpSpline = psSpline1DAllocGeneric(bounds, LINEAR);
+    if (tmpSpline == NULL) {
+        printf("ERROR: Could not allocate psSpline1D data structure\n");
+        testStatus = false;
+    }
+    if (tmpSpline->spline == NULL) {
+        printf("ERROR: Could not allocate psSpline1D->spline data structure\n");
+        testStatus = false;
+    }
+
+    if (tmpSpline->n != N) {
+        printf("ERROR: spline->n set incorrectly (%d)\n", tmpSpline->n);
+        testStatus = false;
+    }
+
+    for (i=0;i<N;i++) {
+        if (tmpSpline->spline[i] == NULL) {
+            printf("ERROR: Could not allocate spline %d\n", i);
+            testStatus = false;
+        }
+        if ((tmpSpline->spline[i])->n != LINEAR+1) {
+            printf("ERROR: Spline created with order %d\n", (tmpSpline->spline[i])->n);
+            testStatus = false;
+        }
+    }
+
+    if (tmpSpline->domains == NULL) {
+        printf("ERROR: Could not allocate psSpline1D->domains data structure\n");
+        testStatus = false;
+    }
+
+    for (i=0;i<N+1;i++) {
+        if (tmpSpline->domains[i] != bounds->data.F32[i]) {
+            printf("ERROR: psSpline1D->domains[%d] is %f\n", i, tmpSpline->domains[i]);
+        }
+    }
+
+    p_psSpline1DFree(tmpSpline);
+    psFree(bounds);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAllocGeneric(): linear",
+                testStatus);
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAllocGeneric(): cubic");
+    bounds = psVectorAlloc(N+1, PS_TYPE_F32);
+    for (i=0;i<N+1;i++) {
+        bounds->data.F32[i] = (float) (3 * i);
+    }
+
+    tmpSpline = psSpline1DAllocGeneric(bounds, CUBIC);
+    if (tmpSpline == NULL) {
+        printf("ERROR: Could not allocate psSpline1D data structure\n");
+        testStatus = false;
+    }
+    if (tmpSpline->spline == NULL) {
+        printf("ERROR: Could not allocate psSpline1D->spline data structure\n");
+        testStatus = false;
+    }
+
+    if (tmpSpline->n != N) {
+        printf("ERROR: spline->n set incorrectly (%d)\n", tmpSpline->n);
+        testStatus = false;
+    }
+
+    for (i=0;i<N;i++) {
+        if (tmpSpline->spline[i] == NULL) {
+            printf("ERROR: Could not allocate spline %d\n", i);
+            testStatus = false;
+        }
+        if ((tmpSpline->spline[i])->n != CUBIC+1) {
+            printf("ERROR: Spline created with order %d\n", (tmpSpline->spline[i])->n);
+            testStatus = false;
+        }
+    }
+
+    if (tmpSpline->domains == NULL) {
+        printf("ERROR: Could not allocate psSpline1D->domains data structure\n");
+        testStatus = false;
+    }
+
+    for (i=0;i<N+1;i++) {
+        if (tmpSpline->domains[i] != bounds->data.F32[i]) {
+            printf("ERROR: psSpline1D->domains[%d] is %f\n", i, tmpSpline->domains[i]);
+        }
+    }
+
+    p_psSpline1DFree(tmpSpline);
+    psFree(bounds);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAllocGeneric(): cubic",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psFunc04.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psFunc04.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psFunc04.c	(revision 2163)
@@ -0,0 +1,127 @@
+/*****************************************************************************
+    This routine must ensure that the psSpline1DEval() function works
+    properly.  It creates a spline with psSpline1DAlloc(), creates a set of
+    data values, sets the spline polynomials with psVectorFitSpline1D(), then
+    calls psSpline1DEval() on new data values and ensures that the results
+    are correct.
+ 
+    XXX: figure out the memory deallocator
+ *****************************************************************************/
+#include <stdio.h>
+#include <math.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psFunctions.h"
+
+#define N 8
+
+int t00()
+{
+    int testStatus = true;
+    int memLeaks=0;
+    int i;
+    float x;
+    float y;
+    int  currentId = psMemGetId();
+    psSpline1D *tmpSpline;
+    psVector *data;
+
+    psTraceSetLevel(".", 0);
+
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAlloc()");
+    data = psVectorAlloc(N+1, PS_TYPE_F32);
+    tmpSpline = psSpline1DAlloc(N, 1, 1.0, 10.0);
+
+    for (i=0;i<N+1;i++) {
+        data->data.F32[i] = tmpSpline->domains[i];
+    }
+    psVectorFitSpline1D(tmpSpline, data, data, NULL);
+
+    for (i=0;i<N+1;i++) {
+        x = 0.5 + (float) i+1;
+        y = psSpline1DEval(tmpSpline, x);
+        if (fabs(x-y) > FLT_EPSILON) {
+            printf("ERROR: f(%f) is %f\n", x, y);
+            testStatus = true;
+        }
+    }
+
+    p_psSpline1DFree(tmpSpline);
+    psMemCheckCorruption(1);
+    psFree(data);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAlloc()",
+                testStatus);
+
+    return (!testStatus);
+}
+
+int t01()
+{
+    int testStatus = true;
+    int memLeaks=0;
+    int i;
+    float x;
+    float y;
+    int  currentId = psMemGetId();
+    psSpline1D *tmpSpline;
+    psVector *data;
+
+    psTraceSetLevel(".", 0);
+
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAlloc()");
+    data = psVectorAlloc(N+1, PS_TYPE_F32);
+    tmpSpline = psSpline1DAlloc(N, 1, 1.0, 10.0);
+
+    for (i=0;i<N+1;i++) {
+        data->data.F32[i] = tmpSpline->domains[i];
+    }
+    psVectorFitSpline1D(tmpSpline, data, data, NULL);
+
+    for (i=0;i<N+1;i++) {
+        x = 0.5 + (float) i+1;
+        y = psSpline1DEval(tmpSpline, x);
+        if (fabs(x-y) > FLT_EPSILON) {
+            printf("ERROR: f(%f) is %f\n", x, y);
+            testStatus = true;
+        }
+    }
+
+    p_psSpline1DFree(tmpSpline);
+    psMemCheckCorruption(1);
+    psFree(data);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAlloc()",
+                testStatus);
+
+    return (!testStatus);
+}
+
+int main()
+{
+    t00();
+    //    t01();
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psFunc05.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psFunc05.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psFunc05.c	(revision 2163)
@@ -0,0 +1,79 @@
+/*****************************************************************************
+    This routine must ensure that the psSpline1DEvalVector() function works
+    properly.  It creates a spline with psSpline1DAlloc(), (1-D functions
+    are used for the spline polynomials) creates a set of data values, sets
+    the spline polynomials with psVectorFitSpline1D(), then calls
+    psSpline1DEvalVector() on new data values and ensures that the results
+    are correct.
+ 
+    XXX: Only F32 types are tested here.  F64 types are tested elsewhere.
+ *****************************************************************************/
+#include <stdio.h>
+#include <math.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psFunctions.h"
+#define N 8
+#define SPLINE_ORDER 1
+
+int main()
+{
+    int testStatus = true;
+    int memLeaks=0;
+    int i;
+    int  currentId = psMemGetId();
+    psSpline1D *tmpSpline;
+    psVector *data;
+    psVector *x;
+    psVector *y;
+
+    psTraceSetLevel(".", 0);
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAlloc()");
+    data = psVectorAlloc(N+1, PS_TYPE_F32);
+    x = psVectorAlloc(N+1, PS_TYPE_F32);
+    tmpSpline = psSpline1DAlloc(N, SPLINE_ORDER, 1.0, 10.0);
+
+    for (i=0;i<N+1;i++) {
+        data->data.F32[i] = tmpSpline->domains[i];
+    }
+
+    psVectorFitSpline1D(tmpSpline, data, data, NULL);
+
+    for (i=0;i<N+1;i++) {
+        x->data.F32[i] = 0.5 + (float) i+1;
+    }
+
+    y = psSpline1DEvalVector(x, tmpSpline);
+
+    for (i=0;i<N+1;i++) {
+        if (fabs(x->data.F32[i]-y->data.F32[i]) > FLT_EPSILON) {
+            printf("ERROR: f(%f) is %f\n", x->data.F32[i], y->data.F32[i]);
+            testStatus = true;
+        }
+    }
+
+    p_psSpline1DFree(tmpSpline);
+
+    psFree(x);
+    psFree(y);
+    psFree(data);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAlloc()",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psFunc07.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psFunc07.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psFunc07.c	(revision 2163)
@@ -0,0 +1,175 @@
+/*****************************************************************************
+This routine must ensure that the psVectorFitSpline1D() function works
+properly.  It creates a spline with psSpline1DAlloc(), creates a set of data
+values, sets the spline polynomials with psVectorFitSpline1D(), then calls
+psSpline1DEval() on new data values and ensures that the results are correct.
+ 
+F32 and F64 versions are used here.
+ 
+XXX: The spline eval functions are F32 only, while the spline fit functions
+are F32 and F64.
+ *****************************************************************************/
+#include <stdio.h>
+#include <math.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psFunctions.h"
+
+#define NUM_SPLINES 50
+#define A 4.0
+#define B -3.0
+#define C 0.2
+#define D 0.1
+#define MIN 1.0
+#define MAX 30
+#define ERROR_TOLERANCE 0.10
+#define OFFSET (NUM_SPLINES * ERROR_TOLERANCE)
+
+float myFunc(float x)
+{
+    return(A + x * (B + x * (C + x * (D))));
+}
+
+int t00()
+{
+    int testStatus = true;
+    int memLeaks=0;
+    int  currentId = psMemGetId();
+    int i;
+    psSpline1D *tmpSpline = NULL;
+    psVector *x = NULL;
+    psVector *newX = NULL;
+    psVector *y = NULL;
+    psVector *newY = NULL;
+
+    psTraceSetLevel(".", 0);
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    x = psVectorAlloc(NUM_SPLINES+1, PS_TYPE_F32);
+    newX = psVectorAlloc(NUM_SPLINES+1, PS_TYPE_F32);
+    y = psVectorAlloc(NUM_SPLINES+1, PS_TYPE_F32);
+    tmpSpline = psSpline1DAlloc(NUM_SPLINES, 3, MIN, MAX);
+
+    for (i=0;i<NUM_SPLINES+1;i++) {
+        x->data.F32[i] = tmpSpline->domains[i];
+        y->data.F32[i] = myFunc(x->data.F32[i]);
+    }
+
+    for (i=0;i<NUM_SPLINES;i++) {
+        newX->data.F32[i]= ((x->data.F32[i] + x->data.F32[i+1])/2.0);
+    }
+    newX->data.F32[NUM_SPLINES] = x->data.F32[NUM_SPLINES];
+    /****************************************************************************/
+    /*   psLib Code      */
+    /****************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAlloc(), psVectorFitSpline1D, psSpline1DEvalVector: F32 versions");
+
+    psVectorFitSpline1D(tmpSpline, x, y, NULL);
+    newY = psSpline1DEvalVector(newX, tmpSpline);
+
+    for (i=OFFSET;i<NUM_SPLINES-OFFSET+1;i++) {
+        if ( fabs( newY->data.F32[i] - myFunc(newX->data.F32[i]) ) > fabs( ERROR_TOLERANCE * myFunc(newX->data.F32[i]) ) ) {
+            printf("ERROR[%d]: f(%f) is %f.  Should be %f\n", i,
+                   newX->data.F32[i], newY->data.F32[i], myFunc(newX->data.F32[i]));
+            testStatus = false;
+        }
+    }
+
+    psFree(x);
+    psFree(newX);
+    psFree(y);
+    p_psSpline1DFree(tmpSpline);
+    psFree(newY);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAlloc(), psVectorFitSpline1D, psSpline1DEvalVector: F32 versions",
+                testStatus);
+
+    return (!testStatus);
+}
+
+// This is the F64 version of the above test code.
+int t01()
+{
+    int testStatus = true;
+    int memLeaks=0;
+    int  currentId = psMemGetId();
+    int i;
+    psSpline1D *tmpSpline = NULL;
+    psVector *x = NULL;
+    psVector *newX = NULL;
+    psVector *y = NULL;
+    psVector *newY = NULL;
+
+    psTraceSetLevel(".", 0);
+    /****************************************************************************/
+    /****************************************************************************/
+    testStatus = true;
+    x = psVectorAlloc(NUM_SPLINES+1, PS_TYPE_F64);
+    newX = psVectorAlloc(NUM_SPLINES+1, PS_TYPE_F64);
+    y = psVectorAlloc(NUM_SPLINES+1, PS_TYPE_F64);
+    tmpSpline = psSpline1DAlloc(NUM_SPLINES, 3, MIN, MAX);
+
+    for (i=0;i<NUM_SPLINES+1;i++) {
+        x->data.F64[i] = tmpSpline->domains[i];
+        y->data.F64[i] = myFunc(x->data.F64[i]);
+    }
+
+    for (i=0;i<NUM_SPLINES;i++) {
+        newX->data.F64[i]= ((x->data.F64[i] + x->data.F64[i+1])/2.0);
+    }
+    newX->data.F64[NUM_SPLINES] = x->data.F64[NUM_SPLINES];
+    /****************************************************************************/
+    /*   psLib Code      */
+    /****************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psFunction functions",
+                            "psSpline1DAlloc(), psVectorFitSpline1D, psSpline1DEvalVector: F64 versions");
+
+    psVectorFitSpline1D(tmpSpline, x, y, NULL);
+    newY = psSpline1DEvalVector(newX, tmpSpline);
+
+    for (i=OFFSET;i<NUM_SPLINES-OFFSET+1;i++) {
+        if ( fabs( newY->data.F32[i] - myFunc(newX->data.F64[i]) ) > fabs( ERROR_TOLERANCE * myFunc((float)newX->data.F64[i]) ) ) {
+            printf("ERROR[%d]: f(%f) is %f.  Should be %f\n", i,
+                   newX->data.F64[i], newY->data.F32[i], myFunc((float)newX->data.F64[i]));
+            testStatus = false;
+        }
+    }
+
+    psFree(x);
+    psFree(newX);
+    psFree(y);
+    p_psSpline1DFree(tmpSpline);
+    psFree(newY);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psFunctions functions",
+                "psSpline1DAlloc(), psVectorFitSpline1D, psSpline1DEvalVector: F64 versions",
+                testStatus);
+
+    return (!testStatus);
+}
+
+int main()
+{
+    t00();
+    t01();
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psHist00.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psHist00.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psHist00.c	(revision 2163)
@@ -0,0 +1,124 @@
+/*****************************************************************************
+    This routine must ensure that the psHistogram structure is correctly
+    allocated and deallocated by the procedure psHistogramAlloc().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#define LOWER 20.0
+#define UPPER 30.0
+
+int main()
+{
+    psHistogram *myHist = NULL;
+    int testStatus      = true;
+    int memLeaks        = 0;
+    int i               = 0;
+    int nb              = 0;
+    int numBins         = 0;
+    int currentId       = 0;
+
+    currentId       = psMemGetId();
+    for (nb=0;nb<4;nb++) {
+        if (nb == 0)
+            numBins = 1;
+        if (nb == 1)
+            numBins = 2;
+        if (nb == 2)
+            numBins = 10;
+        if (nb == 3)
+            numBins = 20;
+        /*********************************************************************/
+        /*  Allocate and initialize data structures                          */
+        /*********************************************************************/
+        printPositiveTestHeader(stdout,
+                                "psStats functions",
+                                "Allocate the psHistogram structure.");
+
+        myHist = psHistogramAlloc(LOWER, UPPER, numBins);
+
+        if (myHist->nums->n != numBins) {
+            printf("ERROR: myHist->nums->n is wrong size (%d)\n", myHist->nums->n);
+            testStatus = false;
+        }
+
+        if (myHist->bounds->n != numBins+1) {
+            printf("ERROR: myHist->bounds->n is wrong size (%d)\n", myHist->bounds->n);
+            testStatus = false;
+        }
+
+        for (i=0;i<numBins;i++) {
+            if (myHist->nums->data.U32[i] != 0) {
+                printf("ERROR: myHist->nums->data.U32[%d] not initialized to 0.\n", i);
+                testStatus = false;
+            }
+            myHist->nums->data.U32[i] = 0;
+        }
+
+        if (myHist->minNum != 0) {
+            printf("ERROR: myHist->minNum is %d\n", myHist->minNum);
+            testStatus = false;
+        }
+
+        if (myHist->maxNum != 0) {
+            printf("myHist->maxNum is %d\n", myHist->maxNum);
+            testStatus = false;
+        }
+
+        if (myHist->uniform != true) {
+            printf("ERROR: myHist->uniform is %d\n", myHist->uniform);
+            testStatus = false;
+        }
+
+        for (i=0;i<numBins;i++) {
+            printf("Bin number %d bounds: (%6.3f - %6.3f)\n", i,
+                   myHist->bounds->data.F32[i],
+                   myHist->bounds->data.F32[i+1]);
+        }
+
+        psMemCheckCorruption(1);
+        psFree(myHist);
+        psMemCheckCorruption(1);
+
+        printFooter(stdout,
+                    "psStats functions",
+                    "Allocate the psHistogram structure.",
+                    testStatus);
+    }
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "Allocate the psHistogram structure. (UPPER<LOWER)");
+
+    myHist = psHistogramAlloc(UPPER, LOWER, numBins);
+    if (myHist != NULL) {
+        printf("ERROR: myHist != NULL\n");
+    }
+    printFooter(stdout,
+                "psStats functions",
+                "Allocate the psHistogram structure. (UPPER<LOWER)",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "Deallocate the psHistogram structure.");
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    printFooter(stdout,
+                "psStats functions",
+                "Deallocate the psHistogram structure.",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psHist01.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psHist01.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psHist01.c	(revision 2163)
@@ -0,0 +1,114 @@
+/*****************************************************************************
+    This routine must ensure that the psHistogram structure is correctly
+    allocated and deallocated by the procedure psHistogramAllocGeneric().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#define LOWER 20.0
+#define UPPER 30.0
+
+int main()
+{
+    psHistogram *myHist = NULL;
+    psVector *myBounds  = NULL;
+    int testStatus      = true;
+    int memLeaks        = 0;
+    int i               = 0;
+    int nb              = 0;
+    int numBins         = 0;
+    int currentId       = 0;
+
+    currentId       = psMemGetId();
+    for (nb=0;nb<4;nb++) {
+        if (nb == 0)
+            numBins = 1;
+        if (nb == 1)
+            numBins = 2;
+        if (nb == 2)
+            numBins = 10;
+        if (nb == 3)
+            numBins = 20;
+        /*********************************************************************/
+        /*  Allocate and initialize data structures                          */
+        /*********************************************************************/
+        printPositiveTestHeader(stdout,
+                                "psStats functions",
+                                "Allocate the psHistogram structure.");
+        myBounds = psVectorAlloc(numBins+1, PS_TYPE_F32);
+        myBounds->n = myBounds->nalloc;
+        for (i=0;i<numBins+1;i++) {
+            myBounds->data.F32[i] = LOWER + ((UPPER - LOWER) / (float) numBins) *
+                                    (float) i;
+        }
+        myHist = psHistogramAllocGeneric(myBounds);
+
+        if (myHist->nums->n != numBins) {
+            printf("ERROR: myHist->nums->n is wrong size (%d)\n", myHist->nums->n);
+            testStatus = false;
+        }
+
+        if (myHist->bounds->n != numBins+1) {
+            printf("ERROR: myHist->bounds->n is wrong size (%d)\n", myHist->bounds->n);
+            testStatus = false;
+        }
+
+        for (i=0;i<numBins;i++) {
+            if (myHist->nums->data.U32[i] != 0) {
+                printf("ERROR: myHist->nums->data.U32[%d] not initialized to 0.\n", i);
+                testStatus = false;
+            }
+            myHist->nums->data.U32[i] = 0;
+        }
+
+        if (myHist->minNum != 0) {
+            printf("ERROR: myHist->minNum is %d\n", myHist->minNum);
+            testStatus = false;
+        }
+
+        if (myHist->maxNum != 0) {
+            printf("myHist->maxNum is %d\n", myHist->maxNum);
+            testStatus = false;
+        }
+
+        if (myHist->uniform != false) {
+            printf("ERROR: myHist->uniform is %d\n", myHist->uniform);
+            testStatus = false;
+        }
+
+        for (i=0;i<numBins;i++) {
+            printf("Bin number %d bounds: (%6.3f - %6.3f)\n", i,
+                   myHist->bounds->data.F32[i],
+                   myHist->bounds->data.F32[i+1]);
+        }
+        psMemCheckCorruption(1);
+        psFree(myHist);
+        psMemCheckCorruption(1);
+        psFree(myBounds);
+
+        printFooter(stdout,
+                    "psStats functions",
+                    "Allocate the psHistogram structure.",
+                    testStatus);
+    }
+    /*************************************************************************/
+    /*  Deallocate data structures                                           */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "Deallocate the psHistogram structure.");
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    printFooter(stdout,
+                "psStats functions",
+                "Deallocate the psHistogram structure.",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psHist02.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psHist02.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psHist02.c	(revision 2163)
@@ -0,0 +1,182 @@
+/*****************************************************************************
+   This routine must ensure that the psHistogram structure is correctly
+   populated by the procedure psGetArrayHistogram().
+ 
+*****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#define MISC_FLOAT_NUMBER 345.0
+#define MISC_INT_NUMBER 345
+#define LOWER 20.0
+#define UPPER 30.0
+#define NUM_DATA 10000
+
+int main()
+{
+    psHistogram * myHist = NULL;
+    psHistogram *myHist2 = NULL;
+    psVector *myData = NULL;
+    psVector *myMask = NULL;
+    int testStatus = true;
+    int memLeaks = 0;
+    int nb = 0;
+    int numBins = 0;
+    int i = 0;
+    int currentId = 0;
+
+    currentId = psMemGetId();
+
+    /*********************************************************************/
+    /*  Allocate and initialize data structures                          */
+    /*********************************************************************/
+    myData = psVectorAlloc( NUM_DATA, PS_TYPE_F32 );
+    myData->n = myData->nalloc;
+    for ( i = 0;i < NUM_DATA;i++ ) {
+        myData->data.F32[ i ] = LOWER + ( ( UPPER - LOWER ) / ( float ) NUM_DATA ) * ( float ) i;
+    }
+
+    myMask = psVectorAlloc( NUM_DATA, PS_TYPE_U8 );
+    myMask->n = myMask->nalloc;
+    for ( i = 0;i < NUM_DATA;i++ ) {
+        if ( i >= ( NUM_DATA / 2 ) ) {
+            myMask->data.U8[ i ] = 1;
+        } else {
+            myMask->data.U8[ i ] = 0;
+        }
+    }
+
+    for ( nb = 0;nb < 4;nb++ ) {
+        if ( nb == 0 )
+            numBins = 1;
+        if ( nb == 1 )
+            numBins = 2;
+        if ( nb == 2 )
+            numBins = 10;
+        if ( nb == 3 )
+            numBins = 20;
+
+        /*********************************************************************/
+        /*  Allocate and Perform Histogram, no mask                          */
+        /*********************************************************************/
+        printPositiveTestHeader( stdout,
+                                 "psStats functions",
+                                 "Allocate and Perform Histogram, no mask" );
+
+        myHist = psHistogramAlloc( LOWER, UPPER, numBins );
+        myHist = psVectorHistogram( myHist, myData, NULL, 0 );
+
+        for ( i = 0;i < numBins;i++ ) {
+            printf( "Bin number %d bounds: (%.2f - %.2f) data (%d)\n", i,
+                    myHist->bounds->data.F32[ i ],
+                    myHist->bounds->data.F32[ i + 1 ],
+                    myHist->nums->data.U32[ i ] );
+        }
+        psMemCheckCorruption( 1 );
+        psFree( myHist );
+        psMemCheckCorruption( 1 );
+
+        printFooter( stdout,
+                     "psStats functions",
+                     "Allocate and Perform Histogram, no mask",
+                     testStatus );
+
+        /*********************************************************************/
+        /*  Allocate and Perform Histogram with mask                         */
+        /*********************************************************************/
+        printPositiveTestHeader( stdout,
+                                 "psStats functions",
+                                 "Allocate and Perform Histogram with mask" );
+
+        myHist = psHistogramAlloc( LOWER, UPPER, numBins );
+        myHist = psVectorHistogram( myHist, myData, myMask, 1 );
+
+        for ( i = 0;i < numBins;i++ ) {
+            printf( "Bin number %d bounds: (%6.3f - %6.3f) data (%d)\n", i,
+                    myHist->bounds->data.F32[ i ],
+                    myHist->bounds->data.F32[ i + 1 ],
+                    myHist->nums->data.U32[ i ] );
+        }
+        psMemCheckCorruption( 1 );
+        psFree( myHist );
+        psMemCheckCorruption( 1 );
+
+        printFooter( stdout,
+                     "psStats functions",
+                     "Allocate and Perform Histogram with mask",
+                     testStatus );
+    }
+    psFree( myMask );
+
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "Calling psVectorHistogram() with various NULL inputs." );
+
+    // Verify the return value is null and program execution doesn't stop,
+    // if input parameter myHist is null.
+
+    myHist2 = psVectorHistogram( NULL, myData, NULL, 0 );
+    if ( myHist2 != NULL ) {
+        printf( "ERROR: myHist2!=NULL\n" );
+        testStatus = false;
+    }
+    psFree( myData );
+
+
+    // Verify the retrun value is the same as the input parameter myHist and
+    // program execution doesn't stop, if the input parameter myArray is
+    // null.
+
+    myHist = psHistogramAlloc( LOWER, UPPER, numBins );
+    myHist = psVectorHistogram( myHist, NULL, NULL, 0 );
+    if ( myHist == NULL ) {
+        printf( "ERROR: myHist==NULL\n" );
+        testStatus = false;
+    }
+    psFree( myHist );
+
+
+    // Verify the return value is the same as the input parameter myHist and
+    // program execution doesn't stop, if the input parameter myArray has no
+    // elements.
+    // NOTE: This code segment is commented out because psVectorAlloc returns
+    // NULL if called with an N element data.
+    /*
+    myData = psVectorAlloc(0, PS_TYPE_F32);
+    myData->n = myData->nalloc;
+    myHist = psHistogramAlloc(LOWER, UPPER, numBins);
+    myHist = psVectorHistogram(myHist, NULL, NULL, 0);
+    if (myHist == NULL) {
+        printf("ERROR: myHist==NULL\n");
+        testStatus = false;
+    }
+    psFree(myHist);
+    psFree(myData);
+    */
+    printFooter( stdout,
+                 "psStats functions",
+                 "Calling psVectorHistogram() with various NULL inputs.",
+                 testStatus );
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "Deallocate the psHistogram structure." );
+
+    psMemCheckCorruption( 1 );
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if ( 0 != memLeaks ) {
+        psAbort( __func__, "Memory Leaks! (%d leaks)", memLeaks );
+    }
+    psMemCheckCorruption( 1 );
+
+    printFooter( stdout,
+                 "psStats functions",
+                 "Deallocate the psHistogram structure.",
+                 testStatus );
+
+    return ( !testStatus );
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psHist03.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psHist03.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psHist03.c	(revision 2163)
@@ -0,0 +1,128 @@
+/*****************************************************************************
+    This routine must ensure that the psHistogram structure is correctly
+    allocated and deallocated by the procedure psHistogramAllocGeneric() and
+    that it can be populated correctly by psVectorHistogram().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#define LOWER 20.0
+#define UPPER 30.0
+#define NUM_DATA 20
+
+int main()
+{
+    psHistogram *myHist = NULL;
+    psVector *myBounds  = NULL;
+    psVector *myData = psVectorAlloc( NUM_DATA, PS_TYPE_F32 );
+    int testStatus      = true;
+    int memLeaks        = 0;
+    int i               = 0;
+    int nb              = 0;
+    int numBins         = 0;
+    int currentId       = 0;
+
+    currentId       = psMemGetId();
+
+    psTraceSetLevel(".psLib", 0);
+
+    myData->n = myData->nalloc;
+    for ( i = 0;i < NUM_DATA;i++ ) {
+        myData->data.F32[ i ] = LOWER + ( ( UPPER - LOWER ) / ( float ) NUM_DATA ) * ( float ) i;
+    }
+
+    for (nb=0;nb<4;nb++) {
+        if (nb == 0)
+            numBins = 1;
+        if (nb == 1)
+            numBins = 2;
+        if (nb == 2)
+            numBins = 10;
+        if (nb == 3)
+            numBins = 20;
+        /*********************************************************************/
+        /*  Allocate and initialize data structures                          */
+        /*********************************************************************/
+        printPositiveTestHeader(stdout,
+                                "psStats functions",
+                                "Allocate the psHistogram structure.");
+        myBounds = psVectorAlloc(numBins+1, PS_TYPE_F32);
+        myBounds->n = myBounds->nalloc;
+        for (i=0;i<numBins+1;i++) {
+            myBounds->data.F32[i] = LOWER + ((UPPER - LOWER) / (float) numBins) *
+                                    (float) i;
+        }
+        myHist = psHistogramAllocGeneric(myBounds);
+
+        if (myHist->nums->n != numBins) {
+            printf("ERROR: myHist->nums->n is wrong size (%d)\n", myHist->nums->n);
+            testStatus = false;
+        }
+
+        if (myHist->bounds->n != numBins+1) {
+            printf("ERROR: myHist->bounds->n is wrong size (%d)\n", myHist->bounds->n);
+            testStatus = false;
+        }
+
+        for (i=0;i<numBins;i++) {
+            if (myHist->nums->data.U32[i] != 0) {
+                printf("ERROR: myHist->nums->data.U32[%d] not initialized to 0.\n", i);
+                testStatus = false;
+            }
+            myHist->nums->data.U32[i] = 0;
+        }
+
+        if (myHist->minNum != 0) {
+            printf("ERROR: myHist->minNum is %d\n", myHist->minNum);
+            testStatus = false;
+        }
+
+        if (myHist->maxNum != 0) {
+            printf("myHist->maxNum is %d\n", myHist->maxNum);
+            testStatus = false;
+        }
+
+        if (myHist->uniform != false) {
+            printf("ERROR: myHist->uniform is %d\n", myHist->uniform);
+            testStatus = false;
+        }
+
+        myHist = psVectorHistogram( myHist, myData, NULL, 0 );
+        for (i=0;i<numBins;i++) {
+            printf("Bin number %d bounds: (%6.3f - %6.3f): data: (%d)\n", i,
+                   myHist->bounds->data.F32[i],
+                   myHist->bounds->data.F32[i+1],
+                   myHist->nums->data.S32[i]);
+        }
+
+        psMemCheckCorruption(1);
+        psFree(myHist);
+        psMemCheckCorruption(1);
+        psFree(myBounds);
+
+        printFooter(stdout,
+                    "psStats functions",
+                    "Allocate the psHistogram structure.",
+                    testStatus);
+    }
+    /*************************************************************************/
+    /*  Deallocate data structures                                           */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "Deallocate the psHistogram structure.");
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    printFooter(stdout,
+                "psStats functions",
+                "Deallocate the psHistogram structure.",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMatrix01.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMatrix01.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMatrix01.c	(revision 2163)
@@ -0,0 +1,92 @@
+/** @file  tst_psMatrix_01.c
+*
+*  @brief Test driver for psMatrix transpose function
+*
+*  This test driver contains the following tests for psMatrix test point 1:
+*     A)  Create input and output images
+*     B)  Transpose input image into output image
+*     C)  Transpose input image into auto allocated NULL output image 
+*     D)  Free images and check for leaks
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.6 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-08-06 22:34:06 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define PRINT_MATRIX(IMAGE)                         \
+for(int i=IMAGE->numRows-1; i>-1; i--) {        \
+    for(int j=0; j<IMAGE->numCols; j++) {       \
+        printf("%f ", IMAGE->data.F64[i][j]);   \
+    }                                          \
+    printf("\n");                              \
+}
+
+int main( int argc,
+          char* argv[] )
+{
+    psImage * tempImage = NULL;
+
+
+    // Test A - Create input and output images
+    printPositiveTestHeader( stdout, "psMatrix", "Create input and output images" );
+    psImage *inImage = ( psImage* ) psImageAlloc( 3, 3, PS_TYPE_F64 );
+    psImage *outImage = ( psImage* ) psImageAlloc( 3, 3, PS_TYPE_F64 );
+    inImage->data.F64[ 0 ][ 0 ] = 1;
+    inImage->data.F64[ 0 ][ 1 ] = 2;
+    inImage->data.F64[ 0 ][ 2 ] = 3;
+    inImage->data.F64[ 1 ][ 0 ] = 4;
+    inImage->data.F64[ 1 ][ 1 ] = 5;
+    inImage->data.F64[ 1 ][ 2 ] = 6;
+    inImage->data.F64[ 2 ][ 0 ] = 7;
+    inImage->data.F64[ 2 ][ 1 ] = 8;
+    inImage->data.F64[ 2 ][ 2 ] = 9;
+    PRINT_MATRIX( inImage );
+    printFooter( stdout, "psMatrix", "Create input and output images", true );
+
+
+    // Test B - Transpose input image into output image
+    printPositiveTestHeader( stdout, "psMatrix", "Transpose input image into output image" );
+    tempImage = outImage;
+    outImage = psMatrixTranspose( outImage, inImage );
+    PRINT_MATRIX( outImage );
+    if ( outImage->type.dimen != PS_DIMEN_IMAGE ) {
+        printf( "Error: Resulting image is not PS_DIMEN_IMAGE\n" );
+    } else
+        if ( outImage != tempImage ) {
+            printf( "Error: Return pointer not equal to output argument pointer\n" );
+        }
+    printFooter( stdout, "psMatrix", "Transpose input image into output image", true );
+
+
+    // Test C -  Transpose input image into auto allocated NULL output image
+    printPositiveTestHeader( stdout, "psMatrix", "ranspose input image into auto allocated NULL output image" );
+    psImage *outImageNull = NULL;
+    outImageNull = psMatrixTranspose( outImageNull, inImage );
+    PRINT_MATRIX( outImageNull );
+    printFooter( stdout, "psMatrix", "ranspose input image into auto allocated NULL output image", true );
+
+
+    // Test D - Free images and check for leaks
+    printPositiveTestHeader( stdout, "psMatrix", "Free images and check for leaks" );
+    psFree( inImage );
+    psFree( outImage );
+    psFree( outImageNull );
+    int nLeaks = psMemCheckLeaks( 0, NULL, stdout );
+    if ( nLeaks != 0 ) {
+        printf( "ERROR: Found %d memory leaks\n", nLeaks );
+    }
+    int nBad = psMemCheckCorruption( 0 );
+    if ( nBad ) {
+        printf( "ERROR: Found %d bad memory blocks\n", nBad );
+    }
+    printFooter( stdout, "psMatrix" , "Free images and check for leaks", true );
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMatrix02.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMatrix02.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMatrix02.c	(revision 2163)
@@ -0,0 +1,71 @@
+/** @file  tst_psMatrix_02.c
+ *
+ *  @brief Test driver for negative tests for psMatrix transpose function
+ *
+ *  This test driver contains the following tests for psMatrix test point 2:
+ *     A)  Input pointer same as output pointer
+ *     B)  Null input psImage
+ *     C)  Incorrect type for input pointer
+ *     D)  Matrix not square for input pointer
+ *     E)  Incorrect type for output pointer
+ *     F)  Matrix not square for output pointer
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.2 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-08-06 22:34:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+int main(int argc,
+         char* argv[])
+{
+    psImage *nullImage = NULL;
+    psImage *inImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    psImage *outImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    psImage *badImage1 = (psImage*)psImageAlloc(3, 3, PS_TYPE_F32);
+    psImage *badImage2 = (psImage*)psImageAlloc(3, 2, PS_TYPE_F64);
+
+    // Test A - Input pointer same as output pointer
+    printNegativeTestHeader(stdout,"psMatrix", "Input pointer same as output pointer",
+                            "Invalid operation: Pointer to inImage is same as outImage.", 0);
+    psMatrixTranspose(inImage, inImage);
+    printFooter(stdout, "psMatrix", "Input pointer same as output pointer", true);
+
+    // Test B - Null input psImage
+    printNegativeTestHeader(stdout,"psMatrix", "Null input psImage",
+                            "Invalid operation: inImage or its data is NULL.", 0);
+    psMatrixTranspose(outImage, nullImage);
+    printFooter(stdout, "psMatrix", "Null input psImage", true);
+
+    // Test C - Incorrect type for input pointer
+    printNegativeTestHeader(stdout,"psMatrix", "Incorrect type for input pointer",
+                            "|Invalid operation: inImage not PS_TYPE_F64.", 0);
+    psMatrixTranspose(outImage, badImage1);
+    printFooter(stdout, "psMatrix", "Incorrect type for input pointer", true);
+
+    // Test D - Matrix not square for input pointer
+    printNegativeTestHeader(stdout,"psMatrix", "Matrix not square for input pointer",
+                            "Invalid operation: inImage not square array.", 0);
+    psMatrixTranspose(outImage, badImage2);
+    printFooter(stdout, "psMatrix", "Matrix not square for input pointer", true);
+
+    // Test E - Incorrect type for output pointer
+    printNegativeTestHeader(stdout,"psMatrix", "Incorrect type for output pointer",
+                            "Invalid operation: outImage not PS_TYPE_F64.", 0);
+    psMatrixTranspose(badImage1, inImage);
+    printFooter(stdout, "psMatrix", "Incorrect type for output pointer", true);
+
+    // Test F - Matrix not square for output pointer
+    printNegativeTestHeader(stdout,"psMatrix", "Matrix not square for output pointer",
+                            "Invalid operation: outImage not square array.", 0);
+    psMatrixTranspose(badImage2, inImage);
+    printFooter(stdout, "psMatrix", "Matrix not square for output pointer", true);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMatrix03.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMatrix03.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMatrix03.c	(revision 2163)
@@ -0,0 +1,146 @@
+/** @file  tst_psMatrix_03.c
+ *
+ *  @brief Test driver for psMatrix LU functions
+ *
+ *  This test driver contains the following tests for psMatrix test point 3:
+ *     A)  Create input and output images and vectors
+ *     B)  Calculate LU matrix
+ *     C)  Determine solution to matrix equation
+ *     D)  Free input and output images and vectors
+ *     E)  Attempt to use null image input argument
+ *     F)  Attempt to use null input vector argument
+ *     G)  ttempt to use null LU image argument
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.8 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-08-06 22:34:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define PRINT_MATRIX(IMAGE)                     \
+for(int i=IMAGE->numRows-1; i>-1; i--) {        \
+    for(int j=0; j<IMAGE->numCols; j++) {       \
+        printf("%f ", IMAGE->data.F64[i][j]);   \
+    }                                           \
+    printf("\n");                               \
+}
+\
+#define PRINT_VECTOR(VECTOR)                    \
+for(int i=0; i<VECTOR->n; i++) {                \
+    printf("%f\n", VECTOR->data.F64[i]);        \
+}
+
+
+int main(int argc,
+         char* argv[])
+{
+    psImage *luImage = NULL;
+    psImage *inImage = NULL;
+    psImage *tempImage = NULL;
+    psVector *tempVector = NULL;
+    psVector *perm = NULL;
+    psVector *outVector = NULL;
+    psVector *inVector = NULL;
+
+
+    // Test A - Create input and output images and vectors
+    printPositiveTestHeader(stdout, "psMatrix", "Create input and output images and vectors");
+    luImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    perm = (psVector*)psVectorAlloc(3, PS_TYPE_F64);
+    outVector = (psVector*)psVectorAlloc(3, PS_TYPE_F64);
+    inVector = (psVector*)psVectorAlloc(3, PS_TYPE_F64);
+    inImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    inImage->data.F64[0][0] =  2;
+    inImage->data.F64[0][1] =  4;
+    inImage->data.F64[0][2] =  6;
+    inImage->data.F64[1][0] =  4;
+    inImage->data.F64[1][1] =  5;
+    inImage->data.F64[1][2] =  6;
+    inImage->data.F64[2][0] =  3;
+    inImage->data.F64[2][1] =  1;
+    inImage->data.F64[2][2] = -2;
+    inVector->data.F64[0] = 18.0;
+    inVector->data.F64[1] = 24.0;
+    inVector->data.F64[2] =  4.0;
+    inVector->n = 3;
+    PRINT_MATRIX(inImage);
+    printf("\n");
+    PRINT_VECTOR(inVector);
+    printFooter(stdout, "psMatrix", "Create input and output images and vectors", true);
+
+
+    // Test B - Calculate LU matrix
+    printPositiveTestHeader(stdout, "psMatrix", "Calculate LU matrix");
+    tempImage = luImage;
+    luImage = psMatrixLUD(luImage, perm, inImage);
+    PRINT_MATRIX(luImage);
+    if(luImage->type.dimen != PS_DIMEN_IMAGE) {
+        printf("Error: Resulting image is not PS_DIMEN_IMAGE\n");
+    } else
+        if(luImage != tempImage) {
+            printf("Error: Return pointer not equal to output argument pointer\n");
+        }
+    printFooter(stdout, "psMatrix", "Calculate LU matrix", true);
+
+
+    // Test C - Determine solution to matrix equation
+    printPositiveTestHeader(stdout, "psMatrix", "Determine solution to matrix equation");
+    tempVector = outVector;
+    outVector = psMatrixLUSolve(outVector, luImage, inVector, perm);
+    PRINT_VECTOR(outVector);
+    if(outVector->type.dimen != PS_DIMEN_VECTOR) {
+        printf("Error: Resulting image is not PS_DIMEN_VECTOR\n");
+    } else
+        if(outVector != tempVector) {
+            printf("Error: Return pointer not equal to output argument pointer\n");
+        }
+    printFooter(stdout, "psMatrix", "Determine solution to matrix equation", true);
+
+
+    // Test D - Free input and output images and vectors
+    printPositiveTestHeader(stdout, "psMatrix", "Free input and output images and vectors");
+    psFree(inImage);
+    psFree(luImage);
+    psFree(perm);
+    psFree(outVector);
+    psFree(inVector);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMatrix" ,"Free input and output images and vectors", true);
+
+
+    // Test E - Attempt to use null image input argument
+    printNegativeTestHeader(stdout,"psMatrix", "Attempt to use null image input argument",
+                            "Invalid operation: inImage or its data is NULL.", 0);
+    psImage *imageTest = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    psMatrixLUD(imageTest, NULL, NULL);
+    printFooter(stdout, "psMatrix", "Attempt to use null image input argument", true);
+
+
+    // Test F - Attempt to use null input vector argument
+    printNegativeTestHeader(stdout,"psMatrix", "Attempt to use null input vector argument",
+                            "Invalid operation: inVector or its data is NULL.", 0);
+    psVector *vectorBad = NULL;
+    psVector *vectorBadOut = (psVector*)psVectorAlloc(3, PS_TYPE_F64);
+    psVector *permBad = (psVector*)psVectorAlloc(3, PS_TYPE_F64);
+    psMatrixLUSolve(vectorBadOut, imageTest, vectorBad, permBad);
+    printFooter(stdout, "psMatrix", "Attempt to use null input vector argument", true);
+
+
+    // Test G - Attempt to use null LU image argument
+    printNegativeTestHeader(stdout,"psMatrix", "Attempt to use null LU image argument",
+                            "Invalid operation: inImage or its data is NULL.", 0);
+    psMatrixLUSolve(vectorBadOut, NULL, vectorBad, permBad);
+    printFooter(stdout, "psMatrix", "Attempt to use null LU image argument", true);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMatrix04.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMatrix04.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMatrix04.c	(revision 2163)
@@ -0,0 +1,112 @@
+/** @file  tst_psMatrix_04.c
+ *
+ *  @brief Test driver for psMatrix invert function
+ *
+ *  This test driver contains the following tests for psMatrix test point 4:
+ *     A)  Create input and output images
+ *     B)  Invert matrix and calculate determinant
+ *     C)  Calculate determinant only
+ *     D)  Free input and output images
+ *     E)  Attempt to use null input image argument
+ *     F)  Attempt to use null input float argument
+ *  
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.4 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-08-06 22:34:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define PRINT_MATRIX(IMAGE)                         \
+for(int i=IMAGE->numRows-1; i>-1; i--) {            \
+    for(int j=0; j<IMAGE->numCols; j++) {           \
+        printf("%f ", IMAGE->data.F64[i][j]);       \
+    }                                               \
+    printf("\n");                                   \
+}
+
+
+int main(int argc,
+         char* argv[])
+{
+    float det = 0.0f;
+    float *det2 = NULL;
+    psImage *outImage = NULL;
+    psImage *inImage = NULL;
+    psImage *tempImage = NULL;
+
+
+    // Test A - Create input and output images
+    printPositiveTestHeader(stdout, "psMatrix", "Create input and output images");
+    outImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    inImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    inImage->data.F64[0][0] =  2;
+    inImage->data.F64[0][1] =  4;
+    inImage->data.F64[0][2] =  3;
+    inImage->data.F64[1][0] =  0;
+    inImage->data.F64[1][1] =  1;
+    inImage->data.F64[1][2] = -1;
+    inImage->data.F64[2][0] =  3;
+    inImage->data.F64[2][1] =  5;
+    inImage->data.F64[2][2] =  7;
+    PRINT_MATRIX(inImage);
+    printFooter(stdout, "psMatrix", "Create input and output images", true);
+
+
+    // Test B - Invert matrix and calculate determinant
+    printPositiveTestHeader(stdout, "psMatrix", "Invert matrix and calculate determinant");
+    tempImage = outImage;
+    outImage = psMatrixInvert(outImage, inImage, &det);
+    PRINT_MATRIX(outImage);
+    printf("\ndet = %f\n", det);
+    if(outImage->type.dimen != PS_DIMEN_IMAGE) {
+        printf("Error: Resulting image is not PS_DIMEN_IMAGE\n");
+    } else
+        if(outImage != tempImage) {
+            printf("Error: Return pointer not equal to output argument pointer\n");
+        }
+    printFooter(stdout, "psMatrix", "Invert matrix and calculate determinant", true);
+
+
+    // Test C - Calculate determinant only
+    printPositiveTestHeader(stdout, "psMatrix", "Calculate determinant only");
+    det2 = psMatrixDeterminant(inImage);
+    printf("det = %f\n", *det2);
+    printFooter(stdout, "psMatrix", "Calculate determinant only", true);
+
+
+    // Test D - Free input and output images
+    printPositiveTestHeader(stdout, "psMatrix", "Free input and output images");
+    psFree(outImage);
+    psFree(inImage);
+    psFree(det2);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMatrix" ,"Free input and output images", true);
+
+
+    // Test E - Attempt to use null input image argument
+    printNegativeTestHeader(stdout,"psMatrix", "Attempt to use null input image argument",
+                            "Invalid operation: inImage or its data is NULL.", 0);
+    psImage *badOutImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    psMatrixInvert(badOutImage, NULL, &det);
+    printFooter(stdout, "psMatrix", "Attempt to use null input image argument", true);
+
+
+    // Test F - Attempt to use null input float argument
+    printNegativeTestHeader(stdout,"psMatrix", "Attempt to use null input float argument",
+                            "Invalid operation: determinant argument is NULL.", 0);
+    psImage *badInImage = (psImage*)psImageAlloc(3, 3, PS_TYPE_F64);
+    psMatrixInvert(badOutImage, badInImage, NULL);
+    printFooter(stdout, "psMatrix", "Attempt to use null input float argument", true);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMatrix05.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMatrix05.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMatrix05.c	(revision 2163)
@@ -0,0 +1,81 @@
+/** @file  tst_psMatrix_05.c
+*
+*  @brief Test driver for psMatrix multiplication function
+*
+*  This test driver contains the following tests for psMatrix test point 5:
+*     A)  Create input and output images
+*     B)  Multiply images
+*     C)  Free input and output images
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.4 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-08-06 22:34:06 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define PRINT_MATRIX(IMAGE)                         \
+for(int i=0; i<IMAGE->numRows; i++) {           \
+    for(int j=0; j<IMAGE->numCols; j++) {       \
+        printf("%f ", IMAGE->data.F64[i][j]);   \
+    }                                          \
+    printf("\n");                              \
+}
+
+
+int main( int argc,
+          char* argv[] )
+{
+    psImage * outImage = NULL;
+    psImage *inImage1 = NULL;
+    psImage *inImage2 = NULL;
+
+
+    // Test A - Create input and output images
+    printPositiveTestHeader( stdout, "psMatrix", "Create input and output images" );
+    outImage = ( psImage* ) psImageAlloc( 2, 2, PS_TYPE_F64 );
+    inImage1 = ( psImage* ) psImageAlloc( 2, 2, PS_TYPE_F64 );
+    inImage2 = ( psImage* ) psImageAlloc( 2, 2, PS_TYPE_F64 );
+    inImage1->data.F64[ 0 ][ 0 ] = 2;
+    inImage1->data.F64[ 0 ][ 1 ] = 3;
+    inImage1->data.F64[ 1 ][ 0 ] = -1;
+    inImage1->data.F64[ 1 ][ 1 ] = 2;
+    inImage2->data.F64[ 0 ][ 0 ] = 4;
+    inImage2->data.F64[ 0 ][ 1 ] = 1;
+    inImage2->data.F64[ 1 ][ 0 ] = 0;
+    inImage2->data.F64[ 1 ][ 1 ] = 6;
+    PRINT_MATRIX( inImage1 );
+    printf( "\n" );
+    PRINT_MATRIX( inImage2 );
+    printFooter( stdout, "psMatrix", "Create input and output images", true );
+
+
+    // Test B - Multiply images
+    printPositiveTestHeader( stdout, "psMatrix", "Multiply images" );
+    psMatrixMultiply( outImage, inImage1, inImage2 );
+    PRINT_MATRIX( outImage );
+    printFooter( stdout, "psMatrix", "Multiply images", true );
+
+
+    // Test C - Free input and output images
+    printPositiveTestHeader( stdout, "psMatrix", "Free input and output images" );
+    psFree( outImage );
+    psFree( inImage1 );
+    psFree( inImage2 );
+    int nLeaks = psMemCheckLeaks( 0, NULL, stdout );
+    if ( nLeaks != 0 ) {
+        printf( "ERROR: Found %d memory leaks\n", nLeaks );
+    }
+    int nBad = psMemCheckCorruption( 0 );
+    if ( nBad ) {
+        printf( "ERROR: Found %d bad memory blocks\n", nBad );
+    }
+    printFooter( stdout, "psMatrix" , "Free input and output images", true );
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMatrix06.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMatrix06.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMatrix06.c	(revision 2163)
@@ -0,0 +1,89 @@
+/** @file  tst_psMatrix_06.c
+*
+*  @brief Test driver for psMatrix Eigenvectors function
+*
+*  This test driver contains the following tests for psMatrix test point 6:
+*     A)  Create input and output images
+*     B)  Calculate Eigenvectors
+*     C)  Free input and output images
+*
+*  @author  Ross Harman, MHPCC
+*
+*  @version $Revision: 1.4 $  $Name: not supported by cvs2svn $
+*  @date  $Date: 2004-08-06 22:34:06 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*
+*/
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define PRINT_MATRIX(IMAGE)                         \
+for(int i=0; i<IMAGE->numRows; i++) {           \
+    for(int j=0; j<IMAGE->numCols; j++) {       \
+        printf("%f ", IMAGE->data.F64[i][j]);   \
+    }                                          \
+    printf("\n");                              \
+}
+
+
+int main( int argc,
+          char* argv[] )
+{
+    psImage * outImage = NULL;
+    psImage *inImage = NULL;
+
+
+    // Test A - Create input and output images
+    printPositiveTestHeader( stdout, "psMatrix", "Create input and output images" );
+    outImage = ( psImage* ) psImageAlloc( 4, 4, PS_TYPE_F64 );
+    inImage = ( psImage* ) psImageAlloc( 4, 4, PS_TYPE_F64 );
+
+    inImage->data.F64[ 0 ][ 0 ] = 1. / 1.;
+    inImage->data.F64[ 0 ][ 1 ] = 1. / 2.;
+    inImage->data.F64[ 0 ][ 2 ] = 1. / 3.;
+    inImage->data.F64[ 0 ][ 3 ] = 1. / 4.;
+
+    inImage->data.F64[ 1 ][ 0 ] = 1. / 2.;
+    inImage->data.F64[ 1 ][ 1 ] = 1. / 3.;
+    inImage->data.F64[ 1 ][ 2 ] = 1. / 4.;
+    inImage->data.F64[ 1 ][ 3 ] = 1. / 5.;
+
+    inImage->data.F64[ 2 ][ 0 ] = 1. / 3.;
+    inImage->data.F64[ 2 ][ 1 ] = 1. / 4.;
+    inImage->data.F64[ 2 ][ 2 ] = 1. / 5.;
+    inImage->data.F64[ 2 ][ 3 ] = 1. / 6.;
+
+    inImage->data.F64[ 3 ][ 0 ] = 1. / 4.;
+    inImage->data.F64[ 3 ][ 1 ] = 1. / 5.;
+    inImage->data.F64[ 3 ][ 2 ] = 1. / 6.;
+    inImage->data.F64[ 3 ][ 3 ] = 1. / 7.;
+
+    PRINT_MATRIX( inImage );
+    printFooter( stdout, "psMatrix", "Create input and output images", true );
+
+
+    // Test B - Calculate Eigenvectors
+    printPositiveTestHeader( stdout, "psMatrix", "Calculate Eigenvectors" );
+    psMatrixEigenvectors( outImage, inImage );
+    PRINT_MATRIX( outImage );
+    printFooter( stdout, "psMatrix", "Calculate Eigenvectors", true );
+
+
+    // Test C - Free input and output images
+    printPositiveTestHeader( stdout, "psMatrix", "Free input and output images" );
+    psFree( outImage );
+    psFree( inImage );
+    int nLeaks = psMemCheckLeaks( 0, NULL, stdout );
+    if ( nLeaks != 0 ) {
+        printf( "ERROR: Found %d memory leaks\n", nLeaks );
+    }
+    int nBad = psMemCheckCorruption( 0 );
+    if ( nBad ) {
+        printf( "ERROR: Found %d bad memory blocks\n", nBad );
+    }
+    printFooter( stdout, "psMatrix" , "Free input and output images", true );
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMatrix07.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMatrix07.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMatrix07.c	(revision 2163)
@@ -0,0 +1,178 @@
+/** @file  tst_psMatrix_07.c
+ *
+ *  @brief Test driver for psMatrix vector conversion functions
+ *
+ *  This test driver contains the following tests for psMatrix test point 7:
+ *     A)  Create input and output images and vectors
+ *     B)  Convert matrix to PS_DIMEN_VECTOR vector
+ *     C)  Attempt to use null image input argument
+ *     D)  Convert matrix to PS_DIMEN_TRANSV vector
+ *     E)  Improper image size
+ *     F)  Convert PS_DIMEN_VECTOR vector to matrix
+ *     G)  Attempt to use null input vector argument
+ *     H)  Convert PS_DIMEN_TRANSV vector to matrix
+ *     I)  Free input and output images and vectors
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-08-06 22:34:06 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define PRINT_MATRIX(IMAGE)                         \
+for(int i=0; i<IMAGE->numRows; i++) {               \
+    for(int j=0; j<IMAGE->numCols; j++) {           \
+        printf("%f ", IMAGE->data.F64[i][j]);       \
+    }                                               \
+    printf("\n");                                   \
+}
+
+#define PRINT_VECTOR(VECTOR)                        \
+for(int i=0; i<VECTOR->n; i++) {                    \
+    printf("%f\n", VECTOR->data.F64[i]);            \
+}
+
+
+int main(int argc,
+         char* argv[])
+{
+    psVector *v1 = NULL;
+    psVector *tempVector = NULL;
+    psImage *tempImage = NULL;
+    psImage *m1 = NULL;
+    psVector *v2 = NULL;
+    psImage *m2 = NULL;
+    psImage *m3 = NULL;
+    psImage *m4 = NULL;
+    psImage *badImage = NULL;
+
+
+    // Test A - Create input and output images
+    printPositiveTestHeader(stdout, "psMatrix", "Create input and output images and vectors");
+    v1 = (psVector*)psVectorAlloc(3, PS_TYPE_F64);
+    m1 = (psImage*)psImageAlloc(1, 3, PS_TYPE_F64);
+    v2 = (psVector*)psVectorAlloc(3, PS_TYPE_F64);
+    m2 = (psImage*)psImageAlloc(1, 3, PS_TYPE_F64);
+    m3 = (psImage*)psImageAlloc(3, 1, PS_TYPE_F64);
+    m4 = (psImage*)psImageAlloc(3, 1, PS_TYPE_F64);
+    badImage = (psImage*)psImageAlloc(2, 2, PS_TYPE_F64);
+    m1->data.F64[0][0] = 0.0;
+    m1->data.F64[1][0] = 1.0;
+    m1->data.F64[2][0] = 2.0;
+    v2->data.F64[0] = 0.0;
+    v2->data.F64[1] = 1.0;
+    v2->data.F64[2] = 2.0;
+    v2->n = 3;
+    m4->data.F64[0][0] = 0.0;
+    m4->data.F64[0][1] = 1.0;
+    m4->data.F64[0][2] = 2.0;
+    PRINT_MATRIX(m1);
+    printf("\n");
+    PRINT_MATRIX(m4);
+    printf("\n");
+    PRINT_VECTOR(v2);
+    printFooter(stdout, "psMatrix", "Create input and output images and vectors", true);
+
+
+    // Test B - Convert matrix to PS_DIMEN_VECTOR vector
+    printPositiveTestHeader(stdout, "psMatrix", "Convert matrix to PS_DIMEN_VECTOR vector");
+    tempVector = v1;
+    v1 = psMatrixToVector(v1, m1);
+    PRINT_VECTOR(v1);
+    if(v1->type.dimen != PS_DIMEN_VECTOR) {
+        printf("Error: Resulting image is not PS_DIMEN_VECTOR\n");
+    } else
+        if(v1 != tempVector) {
+            printf("Error: Return pointer not equal to output argument pointer\n");
+        }
+    printFooter(stdout, "psMatrix", "Convert matrix to PS_DIMEN_VECTOR vector", true);
+
+
+    // Test C - Attempt to use null image input argument
+    printNegativeTestHeader(stdout,"psMatrix", "Attempt to use null image input argument",
+                            "Invalid operation: inImage or its data is NULL.", 0);
+    v1 = psMatrixToVector(v1, NULL);
+    printFooter(stdout, "psMatrix", "Attempt to use null image input argument", true);
+
+
+    // Test D - Convert matrix to PS_DIMEN_TRANSV vector
+    printPositiveTestHeader(stdout, "psMatrix", "Convert matrix to PS_DIMEN_TRANSV vector");
+    v1->type.dimen = PS_DIMEN_TRANSV;
+    psMatrixToVector(v1, m4);
+    PRINT_VECTOR(v1);
+    if(v1->type.dimen != PS_DIMEN_TRANSV) {
+        printf("Error: Resulting image is not PS_DIMEN_TRANSV\n");
+    } else
+        if(v1 != tempVector) {
+            printf("Error: Return pointer not equal to output argument pointer\n");
+        }
+    printFooter(stdout, "psMatrix", "Convert matrix to PS_DIMEN_TRANSV vector", true);
+
+
+    // Test E - Improper image size
+    printNegativeTestHeader(stdout,"psMatrix", "Improper image size",
+                            "Image does not have dim with 1 col or 1 row: (2 x 2).", 0);
+    psMatrixToVector(v1, badImage);
+    printFooter(stdout, "psMatrix", "Improper image size", true);
+
+
+    // Test F - Convert PS_DIMEN_VECTOR vector to matrix
+    printPositiveTestHeader(stdout, "psMatrix", "Convert PS_DIMEN_VECTOR vector to matrix");
+    tempImage = m2;
+    m2 = psVectorToMatrix(m2, v2);
+    PRINT_MATRIX(m2);
+    if(m2->type.dimen != PS_DIMEN_IMAGE) {
+        printf("Error: Resulting image is not PS_DIMEN_IMAGE\n");
+    } else
+        if(m2 != tempImage) {
+            printf("Error: Return pointer not equal to output argument pointer\n");
+        }
+    printFooter(stdout, "psMatrix", "Convert PS_DIMEN_VECTOR vector to matrix", true);
+
+
+    // Test G - Attempt to use null input vector argument
+    printNegativeTestHeader(stdout,"psMatrix", "Attempt to use null input vector argument",
+                            "Invalid operation: inVector or its data is NULL.", 0);
+    psVectorToMatrix(m2, NULL);
+    printFooter(stdout, "psMatrix", "Attempt to use null input vector argument", true);
+
+
+    // Test H - Convert PS_DIMEN_TRANSV vector to matrix
+    printPositiveTestHeader(stdout, "psMatrix", "Convert PS_DIMEN_TRANSV vector to matrix");
+    v2->type.dimen = PS_DIMEN_TRANSV;
+    tempImage = m3;
+    psVectorToMatrix(m3, v2);
+    PRINT_MATRIX(m3);
+    if(m3->type.dimen != PS_DIMEN_IMAGE) {
+        printf("Error: Resulting image is not PS_DIMEN_IMAGE\n");
+    } else
+        if(m3 != tempImage) {
+            printf("Error: Return pointer not equal to output argument pointer\n");
+        }
+    printFooter(stdout, "psMatrix", "Convert PS_DIMEN_TRANSV vector to matrix", true);
+
+
+    // Test I - Free input and output images
+    printPositiveTestHeader(stdout, "psMatrix", "Free input and output images and vectors");
+    psFree(m1);
+    psFree(v1);
+    psFree(m2);
+    psFree(v2);
+    psFree(m3);
+    psFree(m4);
+    psFree(badImage);
+    psMemCheckLeaks(0, NULL, stdout);
+    int nBad = psMemCheckCorruption(0);
+    if(nBad) {
+        printf("ERROR: Found %d bad memory blocks\n", nBad);
+    }
+    printFooter(stdout, "psMatrix" ,"Free input and output images and vectors", true);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMatrixVectorArithmetic01.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMatrixVectorArithmetic01.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMatrixVectorArithmetic01.c	(revision 2163)
@@ -0,0 +1,202 @@
+/** @file  tst_psMatrixVectorArithmetic01.c
+ *
+ *  @brief Test driver for psMatrixVector arithmetic functions
+ *
+ *  This test driver tests combinations of matrix, vector, and scalar binary operations including:
+ *     Matrix-matrix with +,-,*,/ with S32, F32, F64, C32
+ *     Matrix-vector with +,-,*,/ with S32, F32, F64, C32
+ *     Matrix-scalar with +,-,*,/ with S32, F32, F64, C32
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.4 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-08-27 23:31:22 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+#define PRINT_SCALAR(SCALAR,TYPE)                                                                            \
+if(PS_IS_PSELEMTYPE_COMPLEX(SCALAR->type.type)) {                                                        \
+    printf("%f+%fi ", creal(SCALAR->data.TYPE), cimag(SCALAR->data.TYPE));                               \
+} else if(PS_IS_PSELEMTYPE_INT(SCALAR->type.type)) {                                                     \
+    printf("%d ", (int)SCALAR->data.TYPE);                                                               \
+} else {                                                                                                 \
+    printf("%f ", (double)SCALAR->data.TYPE);                                                            \
+}                                                                                                        \
+printf("\n\n");
+
+#define PRINT_VECTOR(VECTOR,TYPE)                                                                            \
+for(int i=0; i<VECTOR->n; i++) {                                                                         \
+    if(PS_IS_PSELEMTYPE_COMPLEX(VECTOR->type.type)) {                                                    \
+        printf("%f+%fi ", creal(VECTOR->data.TYPE[i]), cimag(VECTOR->data.TYPE[i]));                     \
+    } else if(PS_IS_PSELEMTYPE_INT(VECTOR->type.type)) {                                                 \
+        printf("%d ", (int)VECTOR->data.TYPE[i]);                                                        \
+    } else {                                                                                             \
+        printf("%f ", (double)VECTOR->data.TYPE[i]);                                                     \
+    }                                                                                                    \
+}                                                                                                        \
+printf("\n\n");
+
+
+#define PRINT_MATRIX(IMAGE,TYPE)                                                                             \
+for(int i=IMAGE->numRows-1; i>-1; i--) {                                                                 \
+    for(int j=0; j<IMAGE->numCols; j++) {                                                                \
+        if(PS_IS_PSELEMTYPE_COMPLEX(IMAGE->type.type)) {                                                 \
+            printf("%f+%fi ", creal(IMAGE->data.TYPE[i][j]), cimag(IMAGE->data.TYPE[i][j]));             \
+        } else if(PS_IS_PSELEMTYPE_INT(IMAGE->type.type)) {                                              \
+            printf("%d ", (int)IMAGE->data.TYPE[i][j]);                                                  \
+        } else {                                                                                         \
+            printf("%f ", (double)IMAGE->data.TYPE[i][j]);                                               \
+        }                                                                                                \
+    }                                                                                                    \
+    printf("\n");                                                                                        \
+}                                                                                                        \
+printf("\n");
+
+
+#define CREATE_AND_SET_VECTOR(NAME,TYPE,VALUE,SIZE)                                                          \
+psVector *NAME = (psVector*)psVectorAlloc(SIZE, PS_TYPE_##TYPE);                                         \
+for(int i=0; i<SIZE; i++) {                                                                              \
+    NAME->data.TYPE[i] = VALUE;                                                                          \
+}                                                                                                        \
+NAME->n = SIZE;
+
+
+#define CREATE_AND_SET_IMAGE(NAME,TYPE,VALUE,NROWS,NCOLS)                                                    \
+psImage *NAME = (psImage*)psImageAlloc(NCOLS,NROWS,PS_TYPE_##TYPE);                                      \
+for(int i=0; i<NAME->numRows; i++) {                                                                     \
+    for(int j=0; j<NAME->numCols; j++) {                                                                 \
+        NAME->data.TYPE[i][j] = VALUE;                                                                   \
+    }                                                                                                    \
+}
+
+
+#define CHECK_MEMORY                                                                                         \
+psMemCheckLeaks(0, NULL, stdout);                                                                        \
+int nBad = psMemCheckCorruption(0);                                                                      \
+if(nBad) {                                                                                               \
+    printf("ERROR: Found %d bad memory blocks\n", nBad);                                                 \
+}
+
+
+int main(int argc, char* argv[])
+{
+
+    // Test matrix-matrix binary operations
+    #define testBinaryOpMM(OP,TYPE,VALUE1,VALUE2,NROWS,NCOLS)                                                \
+    {                                                                                                        \
+        printPositiveTestHeader(stdout, "psMatrixVectorArithmetic", "Test matrix-matrix psBinaryOp");        \
+        printf("Operation: %s\n", #OP);                                                                      \
+        CREATE_AND_SET_IMAGE(inImage,TYPE,VALUE1,NROWS,NCOLS);                                               \
+        CREATE_AND_SET_IMAGE(outImage,TYPE,VALUE2,NROWS,NCOLS);                                              \
+        printf("Input:\n");                                                                                  \
+        PRINT_MATRIX(inImage,TYPE);                                                                          \
+        PRINT_MATRIX(outImage,TYPE);                                                                         \
+        outImage = (psImage*)psBinaryOp(outImage, inImage, #OP, outImage);                                   \
+        printf("Output:\n");                                                                                 \
+        PRINT_MATRIX(outImage,TYPE);                                                                         \
+        psFree(inImage);                                                                                     \
+        psFree(outImage);                                                                                    \
+        CHECK_MEMORY;                                                                                        \
+        printFooter(stdout, "psMatrixVectorArithmetic", "Test matrix-matrix psBinaryOp", true);              \
+    }
+
+    testBinaryOpMM(+,S32,10,10,3,2);
+    testBinaryOpMM(+,F32,10.0,10.0,3,2);
+    testBinaryOpMM(+,F64,10.0,10.0,3,2);
+    testBinaryOpMM(+,C32,10.0+10.0i,10.0+10.0i,3,2);
+    testBinaryOpMM(-,S32,20,10,3,2);
+    testBinaryOpMM(-,F32,20.0,10.0,3,2);
+    testBinaryOpMM(-,F64,20.0,10.0,3,2);
+    testBinaryOpMM(*,C32,20.0+20.0i,10.0+10.0i,3,2);
+    testBinaryOpMM(*,S32,20,10,3,2);
+    testBinaryOpMM(*,F32,20.0,10.0,3,2);
+    testBinaryOpMM(*,F64,20.0,10.0,3,2);
+    testBinaryOpMM(*,C32,20.0+20.0i,10.0+10.0i,3,2);
+    testBinaryOpMM(/,C32,20.0+20.0i,10.0+10.0i,3,2);
+    testBinaryOpMM(/,S32,20,10,3,2);
+    testBinaryOpMM(/,F32,20.0,10.0,3,2);
+    testBinaryOpMM(/,F64,20.0,10.0,3,2);
+    testBinaryOpMM(/,C32,20.0+20.0i,10.0+10.0i,3,2);
+
+    // Test Matrix-Vector binary operations
+    #define testBinaryOpMV(OP,TYPE,VALUE1,VALUE2,NROWS,NCOLS)                                                \
+    {                                                                                                        \
+        printPositiveTestHeader(stdout, "psMatrixVectorArithmetic", "Test matrix-vector psBinaryOp");        \
+        printf("Operation: %s\n", #OP);                                                                      \
+        CREATE_AND_SET_IMAGE(outImage,TYPE,VALUE1,NROWS,NCOLS);                                              \
+        CREATE_AND_SET_VECTOR(inVector,TYPE,VALUE2,NROWS);                                                   \
+        printf("Input:\n");                                                                                  \
+        PRINT_MATRIX(outImage,TYPE);                                                                         \
+        PRINT_VECTOR(inVector,TYPE);                                                                         \
+        outImage = (psImage*)psBinaryOp(outImage, outImage, #OP, inVector);                                  \
+        printf("Output:\n");                                                                                 \
+        PRINT_MATRIX(outImage,TYPE);                                                                         \
+        psFree(inVector);                                                                                    \
+        psFree(outImage);                                                                                    \
+        CHECK_MEMORY;                                                                                        \
+        printFooter(stdout, "psMatrixVectorArithmetic", "Test matrix-vector psBinaryOp", true);              \
+    }
+
+    testBinaryOpMV(+,S32,10,5,3,2);
+    testBinaryOpMV(+,F32,10.0,5.0,3,2);
+    testBinaryOpMV(+,F64,10.0,5.0,3,2);
+    testBinaryOpMV(+,C32,10.0+10.0i,5.0+5.0i,3,2);
+    testBinaryOpMV(-,S32,20,5,3,2);
+    testBinaryOpMV(-,F32,20.0,5.0,3,2);
+    testBinaryOpMV(-,F64,20.0,5.0,3,2);
+    testBinaryOpMV(*,C32,20.0+20.0i,5.0+5.0i,3,2);
+    testBinaryOpMV(*,S32,20,5,3,2);
+    testBinaryOpMV(*,F32,20.0,5.0,3,2);
+    testBinaryOpMV(*,F64,20.0,5.0,3,2);
+    testBinaryOpMV(*,C32,20.0+20.0i,5.0+5.0i,3,2);
+    testBinaryOpMV(/,C32,20.0+20.0i,5.0+5.0i,3,2);
+    testBinaryOpMV(/,S32,20,5,3,2);
+    testBinaryOpMV(/,F32,20.0,5.0,3,2);
+    testBinaryOpMV(/,F64,20.0,5.0,3,2);
+    testBinaryOpMV(/,C32,20.0+20.0i,5.0+5.0i,3,2);
+
+    // Test Matrix-Scalar binary operations
+    #define testBinaryOpMS(OP,TYPE,VALUE1,VALUE2,NROWS,NCOLS)                                                \
+    {                                                                                                        \
+        printPositiveTestHeader(stdout, "psMatrixVectorArithmetic", "Test matrix-scalar psBinaryOp");        \
+        printf("Operation: %s\n", #OP);                                                                      \
+        CREATE_AND_SET_IMAGE(outImage,TYPE,VALUE1,NROWS,NCOLS);                                              \
+        psScalar *inScalar = (psScalar*)psScalarAlloc(VALUE2,PS_TYPE_##TYPE);                                \
+        printf("Input:\n");                                                                                  \
+        PRINT_MATRIX(outImage,TYPE);                                                                         \
+        PRINT_SCALAR(inScalar,TYPE);                                                                         \
+        outImage = (psImage*)psBinaryOp(outImage, outImage, #OP, psScalarCopy(inScalar));                    \
+        printf("Output:\n");                                                                                 \
+        PRINT_MATRIX(outImage,TYPE);                                                                         \
+        psFree(inScalar);                                                                                    \
+        psFree(outImage);                                                                                    \
+        CHECK_MEMORY;                                                                                        \
+        printFooter(stdout, "psMatrixVectorArithmetic", "Test matrix-scalar psBinaryOp", true);              \
+    }
+
+    testBinaryOpMS(+,S32,10,5,3,2);
+    testBinaryOpMS(+,F32,10.0,5.0,3,2);
+    testBinaryOpMS(+,F64,10.0,5.0,3,2);
+    testBinaryOpMS(+,C32,10.0+10.0i,5.0+5.0i,3,2);
+    testBinaryOpMS(-,S32,20,5,3,2);
+    testBinaryOpMS(-,F32,20.0,5.0,3,2);
+    testBinaryOpMS(-,F64,20.0,5.0,3,2);
+    testBinaryOpMS(*,C32,20.0+20.0i,5.0+5.0i,3,2);
+    testBinaryOpMS(*,S32,20,5,3,2);
+    testBinaryOpMS(*,F32,20.0,5.0,3,2);
+    testBinaryOpMS(*,F64,20.0,5.0,3,2);
+    testBinaryOpMS(*,C32,20.0+20.0i,5.0+5.0i,3,2);
+    testBinaryOpMS(/,C32,20.0+20.0i,5.0+5.0i,3,2);
+    testBinaryOpMS(/,S32,20,5,3,2);
+    testBinaryOpMS(/,F32,20.0,5.0,3,2);
+    testBinaryOpMS(/,F64,20.0,5.0,3,2);
+    testBinaryOpMS(/,C32,20.0+20.0i,5.0+5.0i,3,2);
+
+    return 0;
+}
+
Index: /branches/rel3/psLib/test/dataManip/tst_psMatrixVectorArithmetic02.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMatrixVectorArithmetic02.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMatrixVectorArithmetic02.c	(revision 2163)
@@ -0,0 +1,269 @@
+
+/** @file  tst_psMatrixVectorArithmetic02.c
+ *
+ *  @brief Test driver for psMatrixVector arithmetic functions
+ *
+ *  This test driver tests combinations of matrix, vector, and scalar unary operations including:
+ *     Matrix with all math operators with S32, F32, F64, C32
+ *     Vector with all math operators with S32, F32, F64, C32
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.6 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-10-12 20:50:40 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+#include <math.h>
+
+
+#define CHECK_VECTOR(VECTOR,TYPE,TRUTH)                                                                      \
+for(int i=0; i<VECTOR->n; i++) {                                                                             \
+    if(cabs(VECTOR->data.TYPE[i])-cabs(TRUTH) > FLT_EPSILON){                                                \
+        printf("ERROR:Truth and calculated values don't match for vector operation:\n");                     \
+        if(PS_IS_PSELEMTYPE_COMPLEX(VECTOR->type.type)) {                                                    \
+            printf("Truth: %.2f%+.2fi\n", creal(VECTOR->data.TYPE[i]), cimag(VECTOR->data.TYPE[i]));         \
+            printf("Calculated: %.2f%+.2fi\n", creal(TRUTH), cimag(TRUTH));                                  \
+        } else if(PS_IS_PSELEMTYPE_INT(VECTOR->type.type)) {                                                 \
+            printf("Truth: %d\n", (int)(VECTOR->data.TYPE[i]));                                              \
+            printf("Calculated: %d\n", (int)(TRUTH));                                                        \
+        } else {                                                                                             \
+            printf("Truth: %.2f\n", (double)(VECTOR->data.TYPE[i]));                                         \
+            printf("Calculated: %.2f\n", (double)(TRUTH));                                                   \
+        }                                                                                                    \
+    }                                                                                                        \
+}                                                                                                            \
+printf("\n");
+
+
+#define CHECK_MATRIX(IMAGE,TYPE,TRUTH)                                                                       \
+for(int i=IMAGE->numRows-1; i>-1; i--) {                                                                     \
+    for(int j=0; j<IMAGE->numCols; j++) {                                                                    \
+        if(cabs(IMAGE->data.TYPE[i][j])-cabs(TRUTH) > FLT_EPSILON){                                          \
+            printf("ERROR:Truth and calculated values don't match for matrix operation:\n");                 \
+            if(PS_IS_PSELEMTYPE_COMPLEX(IMAGE->type.type)) {                                                 \
+                printf("Truth: %.2f%+.2fi\n", creal(IMAGE->data.TYPE[i][j]), cimag(IMAGE->data.TYPE[i][j])); \
+                printf("Calculated: %.2f%+.2fi\n", creal(TRUTH), cimag(TRUTH));                              \
+            } else if(PS_IS_PSELEMTYPE_INT(IMAGE->type.type)) {                                              \
+                printf("Truth: %d\n", (int)(IMAGE->data.TYPE[i][j]));                                        \
+                printf("Calculated: %d\n", (int)(TRUTH));                                                    \
+            } else {                                                                                         \
+                printf("Truth: %.2f\n", (double)(IMAGE->data.TYPE[i][j]));                                   \
+                printf("Calculated: %.2f\n", (double)(TRUTH));                                               \
+            }                                                                                                \
+        }                                                                                                    \
+    }                                                                                                        \
+    printf("\n");                                                                                            \
+}                                                                                                            \
+printf("\n");
+
+
+#define CREATE_AND_SET_VECTOR(NAME,TYPE,VALUE,SIZE)                                                          \
+psVector *NAME = (psVector*)psVectorAlloc(SIZE, PS_TYPE_##TYPE);                                             \
+for(int i=0; i<SIZE; i++) {                                                                                  \
+    NAME->data.TYPE[i] = VALUE;                                                                              \
+}                                                                                                            \
+NAME->n = SIZE;
+
+
+#define CREATE_AND_SET_IMAGE(NAME,TYPE,VALUE,NROWS,NCOLS)                                                    \
+psImage *NAME = (psImage*)psImageAlloc(NCOLS,NROWS,PS_TYPE_##TYPE);                                          \
+for(int i=0; i<NAME->numRows; i++) {                                                                         \
+    for(int j=0; j<NAME->numCols; j++) {                                                                     \
+        NAME->data.TYPE[i][j] = VALUE;                                                                       \
+    }                                                                                                        \
+}
+
+
+#define CHECK_MEMORY \
+if( psMemCheckLeaks(0, NULL, stdout) != 0 ) {  \
+    psError(__func__,"Memory leaks detected."); \
+    return 50; \
+} \
+int nBad = psMemCheckCorruption(0); \
+if(nBad) { \
+    psError(__func__,"ERROR: Found %d bad memory blocks\n", nBad); \
+    return 51; \
+}
+
+
+int main( int argc, char* argv[] )
+{
+
+    // Test matrix unary operations
+    #define testUnaryOpM(OP,TYPE,VALUE1,VALUE2,NROWS,NCOLS,TRUTH)                                            \
+    {                                                                                                        \
+        printPositiveTestHeader(stdout, "psMatrixVectorArithmetic", "Test matrix psUnaryOp");                \
+        printf("Operation: %s\n", #OP);                                                                      \
+        CREATE_AND_SET_IMAGE(inImage,TYPE,VALUE1,NROWS,NCOLS);                                               \
+        CREATE_AND_SET_IMAGE(outImage,TYPE,VALUE2,NROWS,NCOLS);                                              \
+        outImage = (psImage*)psUnaryOp(outImage, inImage, #OP);                                              \
+        CHECK_MATRIX(outImage,TYPE,TRUTH);                                                                   \
+        psFree(inImage);                                                                                     \
+        psFree(outImage);                                                                                    \
+        CHECK_MEMORY;                                                                                        \
+        printFooter(stdout, "psMatrixVectorArithmetic", "Test matrix psUnaryOp", true);                      \
+    }
+
+    testUnaryOpM( abs, S32, -10, 0, 3, 2, 10 );
+    testUnaryOpM( abs, F32, -10.0, 0.0, 3, 2, 10.0 );
+    testUnaryOpM( abs, F64, -10.0, 0.0, 3, 2, 10.0 );
+    testUnaryOpM( abs, C32, -10.0 - 10.0i, 0.0 + 0.0i, 3, 2,10+10i );
+    testUnaryOpM( exp, S32, 10, 0, 3, 2, cexp(10));
+    testUnaryOpM( exp, F32, 10.0, 0.0, 3, 2, cexp(10.0) );
+    testUnaryOpM( exp, F64, 10.0, 0.0, 3, 2, cexp(10.0) );
+    testUnaryOpM( exp, C32, 1.0 + 1.0i, 0.0 + 0.0i, 3, 2, cexp(1.0+1.0i) );
+    testUnaryOpM( ln, S32, 10, 0, 3, 2, clog(10) );
+    testUnaryOpM( ln, F32, 10.0, 0.0, 3, 2, clog(10.0) );
+    testUnaryOpM( ln, F64, 10.0, 0.0, 3, 2, clog(10.0) );
+    testUnaryOpM( ln, C32, 10.0 + 10.0i, 0.0 + 0.0i, 3, 2, clog(10.0+10.0i) );
+    testUnaryOpM( ten, S32, 3, 0, 3, 2, 1000 );
+    testUnaryOpM( ten, F32, 3.0, 0.0, 3, 2, 1000 );
+    testUnaryOpM( ten, F64, 3.0, 0.0, 3, 2, 1000 );
+    testUnaryOpM( ten, C32, 1.0 + 0.0i, 0.0 + 0.0i, 3, 2, 10.0 );
+    testUnaryOpM( log, S32, 1000, 0, 3, 2, 3 );
+    testUnaryOpM( log, F32, 1000.0, 0.0, 3, 2, 3 );
+    testUnaryOpM( log, F64, 1000.0, 0.0, 3, 2, 3 );
+    testUnaryOpM( log, C32, 1000.0 + 0.0i, 0.0 + 0.0i, 3, 2, 3 );
+    testUnaryOpM( sin, S32, M_PI_2, 0, 3, 2, 1 );
+    testUnaryOpM( sin, F32, M_PI_2, 0.0, 3, 2, 1.0 );
+    testUnaryOpM( sin, F64, M_PI_2, 0.0, 3, 2, 1.0 );
+    testUnaryOpM( sin, C32, M_PI_2 + 0.0i, 0.0 + 0.0i, 3, 2, 1.0 );
+    testUnaryOpM( dsin, S32, 90, 0, 3, 2 , 1);
+    testUnaryOpM( dsin, F32, 90.0, 0.0, 3, 2, 1.0 );
+    testUnaryOpM( dsin, F64, 90.0, 0.0, 3, 2, 1.0 );
+    testUnaryOpM( dsin, C32, 90.0 + 00.0i, 0.0 + 0.0i, 3, 2, 1.0 );
+    testUnaryOpM( cos, S32, 0, 0, 3, 2, 1 );
+    testUnaryOpM( cos, F32, 0.0, 0.0, 3, 2, 1.0 );
+    testUnaryOpM( cos, F64, 0.0, 0.0, 3, 2, 1.0 );
+    testUnaryOpM( cos, C32, 0.0 + 0.0i, 0.0 + 0.0i, 3, 2, 1.0 );
+    testUnaryOpM( dcos, S32, 0, 0, 3, 2, 1 );
+    testUnaryOpM( dcos, F32, 0.0, 0.0, 3, 2, 1.0 );
+    testUnaryOpM( dcos, F64, 0.0, 0.0, 3, 2, 1.0 );
+    testUnaryOpM( dcos, C32, 0.0 + 0.0i, 0.0 + 0.0i, 3, 2, 1.0 );
+    testUnaryOpM( tan, S32, M_PI_4, 0, 3, 2, 1);
+    testUnaryOpM( tan, F32, M_PI_4, 0.0, 3, 2, 1.0 );
+    testUnaryOpM( tan, F64, M_PI_4, 0.0, 3, 2, 1.0 );
+    testUnaryOpM( tan, C32, M_PI_4 + 0.0i, 0.0 + 0.0i, 3, 2, 1 );
+    testUnaryOpM( dtan, S32, 45, 0, 3, 2, 1 );
+    testUnaryOpM( dtan, F32, 45.0, 0.0, 3, 2, 1.0 );
+    testUnaryOpM( dtan, F64, 45.0, 0.0, 3, 2, 1.0 );
+    testUnaryOpM( dtan, C32, 45.0 + 45.0i, 0.0 + 0.0i, 3, 2, 1.0 );
+    testUnaryOpM( asin, S32, 1, 0, 3, 2, M_PI_2);
+    testUnaryOpM( asin, F32, 1.0, 0.0, 3, 2, M_PI_2  );
+    testUnaryOpM( asin, F64, 1.0, 0.0, 3, 2, M_PI_2);
+    testUnaryOpM( asin, C32, 1.0 + 1.0i, 0.0 + 0.0i, 3, 2, M_PI_2);
+    testUnaryOpM( dasin, S32, 1.0, 0, 3, 2, 90 );
+    testUnaryOpM( dasin, F32, 1.0, 0.0, 3, 2, 90.0 );
+    testUnaryOpM( dasin, F64, 1.0, 0.0, 3, 2, 90.0 );
+    testUnaryOpM( dasin, C32, 1.0 + 1.0i, 0.0 + 0.0i, 3, 2, 90.0 );
+    testUnaryOpM( acos, S32, 0, 0, 3, 2, M_PI_2);
+    testUnaryOpM( acos, F32, 0.0, 0.0, 3, 2, M_PI_2 );
+    testUnaryOpM( acos, F64, 0.0, 0.0, 3, 2, M_PI_2 );
+    testUnaryOpM( acos, C32, 0.0 + 0.0i, 0.0 + 0.0i, 3, 2, M_PI_2 );
+    testUnaryOpM( dacos, S32, 0, 0, 3, 2, 90 );
+    testUnaryOpM( dacos, F32, 0.0, 0.0, 3, 2, 90.0 );
+    testUnaryOpM( dacos, F64, 0.0, 0.0, 3, 2, 90.0 );
+    testUnaryOpM( dacos, C32, 0.0 + 0.0i, 0.0 + 0.0i, 3, 2, 90.0 );
+    testUnaryOpM( atan, S32, 1, 0, 3, 2, M_PI_4);
+    testUnaryOpM( atan, F32, 1.0, 0.0, 3, 2, M_PI_4 );
+    testUnaryOpM( atan, F64, 1.0, 0.0, 3, 2, M_PI_4);
+    testUnaryOpM( atan, C32, 1.0 + 0.0i, 0.0 + 0.0i, 3, 2, M_PI_4);
+    testUnaryOpM( datan, S32, 1, 0, 3, 2, 45 );
+    testUnaryOpM( datan, F32, 1.0, 0.0, 3, 2, 45.0 );
+    testUnaryOpM( datan, F64, 1.0, 0.0, 3, 2, 45.0 );
+    testUnaryOpM( datan, C32, 1.0 + 0.0i, 0.0 + 0.0i, 3, 2, 45.0 );
+
+
+    // Test vector unary operations
+    #define testUnaryOpV(OP,TYPE,VALUE1,VALUE2,SIZE,TRUTH)                                                   \
+    {                                                                                                        \
+        printPositiveTestHeader(stdout, "psMatrixVectorArithmetic", "Test vector psUnaryOp");                \
+        printf("Operation: %s\n", #OP);                                                                      \
+        CREATE_AND_SET_VECTOR(inVector,TYPE,VALUE1,SIZE);                                                    \
+        CREATE_AND_SET_VECTOR(outVector,TYPE,VALUE2,SIZE);                                                   \
+        outVector = (psVector*)psUnaryOp(outVector, inVector, #OP);                                          \
+        CHECK_VECTOR(outVector,TYPE,TRUTH);                                                                  \
+        psFree(inVector);                                                                                    \
+        psFree(outVector);                                                                                   \
+        CHECK_MEMORY;                                                                                        \
+        printFooter(stdout, "psMatrixVectorArithmetic", "Test vector psUnaryOp", true);                      \
+    }
+
+    testUnaryOpV( abs, S32, -10, 0, 3, 10 );
+    testUnaryOpV( abs, F32, -10.0, 0.0, 3, 10.0 );
+    testUnaryOpV( abs, F64, -10.0, 0.0, 3, 10.0 );
+    testUnaryOpV( abs, C32, -10.0 - 10.0i, 0.0 + 0.0i, 3, 10+10i );
+    testUnaryOpV( exp, S32, 10, 0, 3, cexp(10));
+    testUnaryOpV( exp, F32, 10.0, 0.0, 3, cexp(10.0) );
+    testUnaryOpV( exp, F64, 10.0, 0.0, 3, cexp(10.0) );
+    testUnaryOpV( exp, C32, 1.0 + 1.0i, 0.0 + 0.0i, 3, cexp(1.0+1.0i) );
+    testUnaryOpV( ln, S32, 10, 0, 3, clog(10) );
+    testUnaryOpV( ln, F32, 10.0, 0.0, 3, clog(10.0) );
+    testUnaryOpV( ln, F64, 10.0, 0.0, 3, clog(10.0) );
+    testUnaryOpV( ln, C32, 10.0 + 10.0i, 0.0 + 0.0i, 3, clog(10.0+10.0i) );
+    testUnaryOpV( ten, S32, 3, 0, 3, 1000 );
+    testUnaryOpV( ten, F32, 3.0, 0.0, 3, 1000 );
+    testUnaryOpV( ten, F64, 3.0, 0.0, 3, 1000 );
+    testUnaryOpV( ten, C32, 1.0 + 0.0i, 0.0 + 0.0i, 3, 10.0 );
+    testUnaryOpV( log, S32, 1000, 0, 3,  3 );
+    testUnaryOpV( log, F32, 1000.0, 0.0, 3, 3 );
+    testUnaryOpV( log, F64, 1000.0, 0.0, 3, 3 );
+    testUnaryOpV( log, C32, 1000.0 + 0.0i, 0.0 + 0.0i, 3, 3 );
+    testUnaryOpV( sin, S32, M_PI_2, 0, 3, 1 );
+    testUnaryOpV( sin, F32, M_PI_2, 0.0, 3, 1.0 );
+    testUnaryOpV( sin, F64, M_PI_2, 0.0, 3, 1.0 );
+    testUnaryOpV( sin, C32, M_PI_2 + 0.0i, 0.0 + 0.0i, 3, 1.0 );
+    testUnaryOpV( dsin, S32, 90, 0, 3, 1);
+    testUnaryOpV( dsin, F32, 90.0, 0.0, 3, 1.0 );
+    testUnaryOpV( dsin, F64, 90.0, 0.0, 3, 1.0 );
+    testUnaryOpV( dsin, C32, 90.0 + 00.0i, 0.0 + 0.0i, 3, 1.0 );
+    testUnaryOpV( cos, S32, 0, 0, 3, 1 );
+    testUnaryOpV( cos, F32, 0.0, 0.0, 3, 1.0 );
+    testUnaryOpV( cos, F64, 0.0, 0.0, 3, 1.0 );
+    testUnaryOpV( cos, C32, 0.0 + 0.0i, 0.0 + 0.0i, 3, 1.0 );
+    testUnaryOpV( dcos, S32, 0, 0, 3, 1 );
+    testUnaryOpV( dcos, F32, 0.0, 0.0, 3, 1.0 );
+    testUnaryOpV( dcos, F64, 0.0, 0.0, 3, 1.0 );
+    testUnaryOpV( dcos, C32, 0.0 + 0.0i, 0.0 + 0.0i, 3, 1.0 );
+    testUnaryOpV( tan, S32, M_PI_4, 0, 3, 1);
+    testUnaryOpV( tan, F32, M_PI_4, 0.0, 3, 1.0 );
+    testUnaryOpV( tan, F64, M_PI_4, 0.0, 3, 1.0 );
+    testUnaryOpV( tan, C32, M_PI_4 + 0.0i, 0.0 + 0.0i, 3, 1 );
+    testUnaryOpV( dtan, S32, 45, 0, 3, 1 );
+    testUnaryOpV( dtan, F32, 45.0, 0.0, 3, 1.0 );
+    testUnaryOpV( dtan, F64, 45.0, 0.0, 3, 1.0 );
+    testUnaryOpV( dtan, C32, 45.0 + 45.0i, 0.0 + 0.0i, 3, 1.0 );
+    testUnaryOpV( asin, S32, 1, 0, 3, M_PI_2);
+    testUnaryOpV( asin, F32, 1.0, 0.0, 3, M_PI_2  );
+    testUnaryOpV( asin, F64, 1.0, 0.0, 3, M_PI_2);
+    testUnaryOpV( asin, C32, 1.0 + 1.0i, 0.0 + 0.0i, 3, M_PI_2);
+    testUnaryOpV( dasin, S32, 1.0, 0, 3, 90 );
+    testUnaryOpV( dasin, F32, 1.0, 0.0, 3, 90.0 );
+    testUnaryOpV( dasin, F64, 1.0, 0.0, 3, 90.0 );
+    testUnaryOpV( dasin, C32, 1.0 + 1.0i, 0.0 + 0.0i, 3, 90.0 );
+    testUnaryOpV( acos, S32, 0, 0, 3, M_PI_2);
+    testUnaryOpV( acos, F32, 0.0, 0.0, 3, M_PI_2 );
+    testUnaryOpV( acos, F64, 0.0, 0.0, 3, M_PI_2 );
+    testUnaryOpV( acos, C32, 0.0 + 0.0i, 0.0 + 0.0i, 3, M_PI_2 );
+    testUnaryOpV( dacos, S32, 0, 0, 3, 90 );
+    testUnaryOpV( dacos, F32, 0.0, 0.0, 3, 90.0 );
+    testUnaryOpV( dacos, F64, 0.0, 0.0, 3, 90.0 );
+    testUnaryOpV( dacos, C32, 0.0 + 0.0i, 0.0 + 0.0i, 3, 90.0 );
+    testUnaryOpV( atan, S32, 1, 0, 3, M_PI_4);
+    testUnaryOpV( atan, F32, 1.0, 0.0, 3, M_PI_4 );
+    testUnaryOpV( atan, F64, 1.0, 0.0, 3, M_PI_4);
+    testUnaryOpV( atan, C32, 1.0 + 0.0i, 0.0 + 0.0i, 3, M_PI_4);
+    testUnaryOpV( datan, S32, 1, 0, 3, 45 );
+    testUnaryOpV( datan, F32, 1.0, 0.0, 3, 45.0 );
+    testUnaryOpV( datan, F64, 1.0, 0.0, 3, 45.0 );
+    testUnaryOpV( datan, C32, 1.0 + 0.0i, 0.0 + 0.0i, 3, 45.0 );
+
+    return 0;
+}
+
Index: /branches/rel3/psLib/test/dataManip/tst_psMatrixVectorArithmetic03.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMatrixVectorArithmetic03.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMatrixVectorArithmetic03.c	(revision 2163)
@@ -0,0 +1,247 @@
+/** @file  tst_psMatrixVectorArithmetic03.c
+ *
+ *  @brief Test driver for psMatrixVector arithmetic functions
+ *
+ *  This test driver contains negative tests for psBinaryOp and psUanryOp:
+ *     Check for NULL arguments
+ *     Inconsistent element types
+ *     Inconsistent element count
+ *     Inconsistent dimensionality
+ *     Division by zero
+ *     Attempt to use min with complex numbers
+ *     Attempt to use max with complex numbers
+ *     Invalid operation
+ *
+ *  @author  Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.5 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-10-12 19:18:20 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+
+#define PRINT_VECTOR(VECTOR,TYPE)                                                                            \
+for(int i=0; i<VECTOR->n; i++) {                                                                         \
+    if(PS_IS_PSELEMTYPE_COMPLEX(VECTOR->type.type)) {                                                    \
+        printf("%f+%fi ", creal(VECTOR->data.TYPE[i]), cimag(VECTOR->data.TYPE[i]));                     \
+    } else if(PS_IS_PSELEMTYPE_INT(VECTOR->type.type)) {                                                 \
+        printf("%d ", (int)VECTOR->data.TYPE[i]);                                                        \
+    } else {                                                                                             \
+        printf("%f ", (double)VECTOR->data.TYPE[i]);                                                     \
+    }                                                                                                    \
+}                                                                                                        \
+printf("\n\n");
+
+
+#define PRINT_MATRIX(IMAGE,TYPE)                                                                             \
+for(int i=IMAGE->numRows-1; i>-1; i--) {                                                                 \
+    for(int j=0; j<IMAGE->numCols; j++) {                                                                \
+        if(PS_IS_PSELEMTYPE_COMPLEX(IMAGE->type.type)) {                                                 \
+            printf("%f+%fi ", creal(IMAGE->data.TYPE[i][j]), cimag(IMAGE->data.TYPE[i][j]));             \
+        } else if(PS_IS_PSELEMTYPE_INT(IMAGE->type.type)) {                                              \
+            printf("%d ", (int)IMAGE->data.TYPE[i][j]);                                                  \
+        } else {                                                                                         \
+            printf("%f ", (double)IMAGE->data.TYPE[i][j]);                                               \
+        }                                                                                                \
+    }                                                                                                    \
+    printf("\n");                                                                                        \
+}                                                                                                        \
+printf("\n");
+
+
+#define CREATE_AND_SET_VECTOR(NAME,TYPE,VALUE,SIZE)                                                          \
+psVector *NAME = (psVector*)psVectorAlloc(SIZE, PS_TYPE_##TYPE);                                         \
+for(int i=0; i<SIZE; i++) {                                                                              \
+    NAME->data.TYPE[i] = VALUE;                                                                          \
+}                                                                                                        \
+NAME->n = SIZE;
+
+
+#define CREATE_AND_SET_IMAGE(NAME,TYPE,VALUE,NROWS,NCOLS)                                                    \
+psImage *NAME = (psImage*)psImageAlloc(NCOLS,NROWS,PS_TYPE_##TYPE);                                      \
+for(int i=0; i<NAME->numRows; i++) {                                                                     \
+    for(int j=0; j<NAME->numCols; j++) {                                                                 \
+        NAME->data.TYPE[i][j] = VALUE;                                                                   \
+    }                                                                                                    \
+}
+
+
+int main(int argc, char* argv[])
+{
+    CREATE_AND_SET_IMAGE(image1,F64,0,3,3);
+    CREATE_AND_SET_IMAGE(image2,F64,0,3,3);
+    CREATE_AND_SET_IMAGE(image3,F32,0,3,3);
+    CREATE_AND_SET_IMAGE(image4,F64,0,2,2);
+    CREATE_AND_SET_IMAGE(image5,C32,1+1i,3,3);
+    CREATE_AND_SET_VECTOR(vector1,F64,0,2);
+    CREATE_AND_SET_VECTOR(vector2,F64,0,3);
+
+
+    // Check for NULL arguments
+    printNegativeTestHeader(stdout,"psMatrixVectorArithmetic", "Check for NULL arguments",
+                            "Null XXX argument", 0);
+    psImage* image6 = (psImage*)psBinaryOp(NULL, image1, "+", image2);
+    if (image6 == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psBinaryOp failed to make an image given no output to recycle.");
+        return 1;
+    }
+
+    image6 = (psImage*)psBinaryOp(image6, NULL, "+", image2);
+    if (image6 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psBinaryOp returned a result given a NULL first operand.");
+        return 2;
+    }
+
+    image6 = (psImage*)psBinaryOp(image6, image1, "+", NULL);
+    if (image6 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psBinaryOp returned a result given a NULL second operand.");
+        return 3;
+    }
+    image6 = (psImage*)psBinaryOp(image6, image1, NULL, image2);
+    if (image6 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psBinaryOp returned a result given a NULL operator.");
+        return 4;
+    }
+
+    image6 = (psImage*)psUnaryOp(NULL, image1, "sin");
+    if (image6 == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psUnaryOp failed to make an image given no output to recycle.");
+        return 5;
+    }
+
+    image6 = (psImage*)psUnaryOp(image6, NULL, "sin");
+    if (image6 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psUnaryOp returned a result given a NULL operand.");
+        return 6;
+    }
+
+    image6 = (psImage*)psUnaryOp(image6, image1, NULL);
+    if (image6 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psUnaryOp returned a result given a NULL operator.");
+        return 7;
+    }
+
+    printFooter(stdout, "psMatrixVectorArithmetic", "Check for NULL arguments", true);
+
+    // Inconsistent element types
+    printNegativeTestHeader(stdout,"psMatrixVectorArithmetic", "Inconsistent element types",
+                            "Element types for arguments inconsistent", 0);
+    image6 = (psImage*)psBinaryOp(image6, image3, "+", image2);
+    if (image6 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psBinaryOp returned a result given operands of different types.");
+        return 8;
+    }
+
+    image6 = psImageCopy(image6,image2,PS_TYPE_F64);
+    image6 = (psImage*)psUnaryOp(image6, image3, "sin");
+    if (image6 == NULL || image6->type.type != PS_TYPE_F32) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psUnaryOp failed to convert the type of the output.");
+        return 9;
+    }
+
+    printFooter(stdout, "psMatrixVectorArithmetic", "Inconsistent element types", true);
+
+
+    // Inconsistent element count
+    printNegativeTestHeader(stdout,"psMatrixVectorArithmetic", "Inconsistent element count",
+                            "Inconsistent element count", 0);
+    image6 = (psImage*)psBinaryOp(image6, image4, "+", image2);
+    if (image6 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psBinaryOp returned a result given operands of different sizes.");
+        return 10;
+    }
+
+    image6 = psImageCopy(image6,image2,PS_TYPE_F64);
+    image6 = (psImage*)psUnaryOp(image6, image4, "sin");
+    if (image6 == NULL ||
+            image6->numCols != image6->numCols ||
+            image6->numRows != image6->numRows) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psUnaryOp failed to resize the output.");
+        return 11;
+    }
+
+    image6 = (psImage*)psBinaryOp(image6, vector1, "+", image2);
+    if (image6 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psBinaryOp returned a result given operands of different sizes.");
+        return 12;
+    }
+
+    vector1->type.dimen = PS_DIMEN_TRANSV;
+    image6 = (psImage*)psBinaryOp(image6, vector1, "+", image2);
+    if (image6 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psBinaryOp returned a result given operands of different sizes.");
+        return 13;
+    }
+    printFooter(stdout, "psMatrixVectorArithmetic", "Inconsistent element count", true);
+
+
+    // Inconsistent dimensionality
+    printNegativeTestHeader(stdout,"psMatrixVectorArithmetic", "Inconsistent dimensionality",
+                            "Dimensionality for arguments inconsistent", 0);
+    image6 = psImageCopy(image6,image2,PS_TYPE_F64);
+    image6 = (psImage*)psUnaryOp(image6, vector2, "sin");
+    if (image6 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,"psUnaryOp returned result given wrong type out parameter.");
+        return 14;
+    }
+
+    printFooter(stdout, "psMatrixVectorArithmetic", "Inconsistent dimensionality", true);
+
+    // Attempt to use min with complex numbers
+    printNegativeTestHeader(stdout,"psMatrixVectorArithmetic", "Use min with complex numbers",
+                            "Minimum operation not supported for complex numbers", 0);
+    image6 = (psImage*)psBinaryOp(image6, image5, "min", image5);
+    printFooter(stdout, "psMatrixVectorArithmetic", "Use min with complex numbers", true);
+
+
+    // Attempt to use max with complex numbers
+    printNegativeTestHeader(stdout,"psMatrixVectorArithmetic", "Use max with complex numbers",
+                            "Maximum operation not supported for complex numbers", 0);
+    image6 = (psImage*)psBinaryOp(image6, image5, "max", image5);
+    printFooter(stdout, "psMatrixVectorArithmetic", "Use max with complex numbers", true);
+
+
+    // Invalid operation
+    printNegativeTestHeader(stdout,"psMatrixVectorArithmetic", "Invalid operation",
+                            "Invalid operation", 0);
+    image6 = (psImage*)psBinaryOp(image6, image1, "yarg", image2);
+    image6 = (psImage*)psUnaryOp(image6, image1, "yarg");
+    printFooter(stdout, "psMatrixVectorArithmetic", "Invalid operation", true);
+
+    // Invalid parameter in2
+    printNegativeTestHeader(stdout,"psMatrixVectorArithmetic","Invalid input",
+                            "Invalid operation", 0);
+    CREATE_AND_SET_VECTOR(vector4,F64,0,3);
+    CREATE_AND_SET_VECTOR(vector5,F64,0,3);
+    CREATE_AND_SET_VECTOR(vector6,F64,0,3);
+    if ( psBinaryOp(vector6,vector4,"+",NULL) != NULL ) {
+        psError(__func__,"psBinaryOp should return null when out and in1 valid but in2 null.");
+        return 10;
+    }
+    printFooter(stdout, "psMatrixVectorArithmetic", "Invalid input", true);
+
+    vector4->type.dimen = PS_DIMEN_OTHER;
+    if ( psBinaryOp(NULL,vector4,"+",vector5) != NULL) {
+        psError(__func__,"psBinaryOp should return null when input dimen PS_DIMEN_OTHER.");
+        return 11;
+    }
+    vector4->type.dimen = PS_DIMEN_VECTOR;
+
+    psScalar* inScalar = psScalarAlloc(0,PS_TYPE_F64);
+    CREATE_AND_SET_IMAGE(image10,F64,0,3,3);
+    if ( psBinaryOp(image10,inScalar,"+",vector4) == NULL ) {
+        psError(__func__,"psBinaryOp should not return null when input/out dimension don't match.");
+        return 12;
+    }
+
+    psFree(vector4);
+    psFree(vector5);
+
+    return 0;
+}
+
Index: /branches/rel3/psLib/test/dataManip/tst_psMinimize00.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMinimize00.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMinimize00.c	(revision 2163)
@@ -0,0 +1,166 @@
+/*****************************************************************************
+    This routine must ensure that the psMinimizeChi2 function correctly
+    minimizes an arbitrary function.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psVector.h"
+#include "psImage.h"
+#include "psFunctions.h"
+#include "psMinimize.h"
+#include <math.h>
+#define NUM_DATA 10
+#define DATA_WIDTH 2
+#define NUM_PARAMS 4
+
+float myFunc(const psVector *restrict myData,
+             const psVector *restrict myParams)
+{
+    float x = myData->data.F32[0];
+    float y = myData->data.F32[1];
+    float A = myParams->data.F32[0];
+    float B = myParams->data.F32[1];
+    float C = myParams->data.F32[2];
+    float D = myParams->data.F32[3];
+    float tmp = 0.0;
+
+    tmp = (A * x) + (B*x*x) + (C*y*y) + (D*x*x*y);
+    //    printf("--------- myFunc((%.1f %.1f) %.1f %.1f %.1f %.1f) is %.1f ---------\n",
+    //           x, y, A, B, C, D, tmp);
+
+    return(tmp);
+}
+
+float myFuncDeriv(const psVector *restrict myData,
+                  const psVector *restrict myParams,
+                  int whichParamDeriv)
+{
+    float x = myData->data.F32[0];
+    float y = myData->data.F32[1];
+    float tmp = 0.0;
+
+    if (whichParamDeriv == 0) {
+        tmp = 1.0;
+        tmp = x;
+    } else
+        if (whichParamDeriv == 1) {
+            tmp = x;
+            tmp = x*x;
+        } else
+            if (whichParamDeriv == 2) {
+                tmp = y;
+                tmp = y*y;
+            } else
+                if (whichParamDeriv == 3) {
+                    tmp = x * x * y;
+                }
+
+    //    printf("--------- myFuncDeriv((%.1f %.1f) %.1f %.1f %.1f %.1f (%d)) is %.1f ---------\n",
+    //            x, y, myParams->data.F32[0], myParams->data.F32[1],
+    //            myParams->data.F32[2], myParams->data.F32[3], whichParamDeriv, tmp);
+    return(tmp);
+}
+
+
+int main()
+{
+    psImage *domain = NULL;
+    psVector *data = NULL;
+    psVector *errors = NULL;
+    psVector *initialGuess = NULL;
+    psVector *paramMask = NULL;
+    psVector *tmpVecPtr = NULL;
+    float chiSq = 0.0;
+    int i = 0;
+    int j = 0;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+    psVector *theParams = NULL;
+
+    domain = psImageAlloc(DATA_WIDTH, NUM_DATA, PS_TYPE_F32);
+    data = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+    errors = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+    initialGuess = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    paramMask = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    tmpVecPtr = psVectorAlloc(DATA_WIDTH, PS_TYPE_F32);
+
+
+    //--------- myFunc((0.0 1.0) -8.6 -7.6 14.6 5.0) is 6.0 ---------
+
+    initialGuess->data.F32[0] = -8.6;
+    initialGuess->data.F32[1] = -7.6;
+    initialGuess->data.F32[2] = 14.6;
+    initialGuess->data.F32[3] = 5.0;
+
+    // Build the data.
+    initialGuess->data.F32[0] = 2.0;
+    initialGuess->data.F32[1] = 3.0;
+    initialGuess->data.F32[2] = 4.0;
+    initialGuess->data.F32[3] = 5.0;
+
+
+    for (i = 0; i<NUM_DATA; i++) {
+        for (j=0; j<DATA_WIDTH; j++) {
+            domain->data.F32[i][j] = (float) (i + j);
+        }
+    }
+    for (i = 0; i<NUM_DATA; i++) {
+        errors->data.F32[i] = 0.1;
+    }
+
+    //    printf("========== Setting Data Values ==========\n");
+    for (i = 0; i<NUM_DATA; i++) {
+        for (j=0; j<DATA_WIDTH; j++) {
+            tmpVecPtr->data.F32[j] = domain->data.F32[i][j];
+        }
+        data->data.F32[i] = myFunc(tmpVecPtr, initialGuess);
+    }
+    //    printf("=========================================\n");
+
+    for (i=0;i<NUM_PARAMS;i++) {
+        initialGuess->data.F32[i]+= 1.0;
+    }
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psMinimizeChi2(): no masks");
+
+    theParams = psMinimizeChi2(myFunc,
+                               myFuncDeriv,
+                               domain,
+                               data,
+                               errors,
+                               initialGuess,
+                               NULL,
+                               &chiSq);
+    for (i=0;i<NUM_PARAMS;i++) {
+        printf("theParams[%d] is %.1f\n", i, theParams->data.F32[i]);
+    }
+
+    printf("chiSq is %f\n", chiSq);
+    psMemCheckCorruption(1);
+    printFooter(stdout,
+                "psMinimize functions",
+                "psMinimizeChi2(): no masks",
+                testStatus);
+
+
+    psMemCheckCorruption(1);
+    psFree(domain);
+    psFree(data);
+    psFree(errors);
+    psFree(initialGuess);
+    psFree(paramMask);
+    psFree(tmpVecPtr);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMinimize01.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMinimize01.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMinimize01.c	(revision 2163)
@@ -0,0 +1,172 @@
+/*****************************************************************************
+    This routine must ensure that the psMinimizeChi2 function correctly
+    minimizes an arbitrary function.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psVector.h"
+#include "psImage.h"
+#include "psFunctions.h"
+#include "psMinimize.h"
+#include <math.h>
+#define NUM_DATA 40
+#define DATA_WIDTH 1
+#define NUM_PARAMS 3
+
+// The function is f(x) = (A * e^(lambda x)) + b
+
+float myFunc(const psVector *restrict myData,
+             const psVector *restrict myParams)
+{
+    float x = myData->data.F32[0];
+    float A = myParams->data.F32[0];
+    float lambda = myParams->data.F32[1];
+    float b = myParams->data.F32[2];
+    float tmp = A * exp(-lambda * x) + b;
+
+    //    printf("--------- myFunc((%.1f) %.1f %.1f %.1f) is %.1f ---------\n",
+    //           x, A, lambda, b, tmp);
+
+    return(tmp);
+}
+
+float myFuncDeriv(const psVector *restrict myData,
+                  const psVector *restrict myParams,
+                  int whichParamDeriv)
+{
+    float x = myData->data.F32[0];
+    float A = myParams->data.F32[0];
+    float lambda = myParams->data.F32[1];
+    float tmp = 0.0;
+
+    if (whichParamDeriv == 0) {
+        tmp = exp(-lambda * x);
+    } else
+        if (whichParamDeriv == 1) {
+            tmp = -x * A * exp(-lambda * x);
+        } else
+            if (whichParamDeriv == 2) {
+                tmp = 1.0;
+            }
+
+    //    printf("--------- myFuncDeriv((%.1f) %.1f %.1f %.1f, %d) is %.1f ---------\n",
+    //           x, A, lambda, myParams->data.F32[2], whichParamDeriv, tmp);
+
+    return(tmp);
+}
+
+int main()
+{
+    psImage *domain = NULL;
+    psVector *data = NULL;
+    psVector *errors = NULL;
+    psVector *initialGuess = NULL;
+    psVector *paramMask = NULL;
+    psVector *tmpVecPtr = NULL;
+    float chiSq = 0.0;
+    int i = 0;
+    psVector *theParams = NULL;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+
+    domain = psImageAlloc(DATA_WIDTH, NUM_DATA, PS_TYPE_F32);
+    data = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+    errors = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+    initialGuess = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    paramMask = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    tmpVecPtr = psVectorAlloc(DATA_WIDTH, PS_TYPE_F32);
+
+    // Build the data.
+    initialGuess->data.F32[0] = 1.0;
+    initialGuess->data.F32[1] = 0.0;
+    initialGuess->data.F32[2] = 0.0;
+
+    for (i = 0; i<NUM_DATA; i++) {
+        errors->data.F32[i] = 0.1;
+        domain->data.F32[i][0] = (float) i;
+    }
+
+    printf("========== Setting Data Values ==========\n");
+    data->data.F32[0] = 6.013392;
+    data->data.F32[1] = 5.515377;
+    data->data.F32[2] = 5.261095;
+    data->data.F32[3] = 4.777455;
+    data->data.F32[4] = 4.451353;
+    data->data.F32[5] = 3.904903;
+    data->data.F32[6] = 3.504387;
+    data->data.F32[7] = 3.414999;
+    data->data.F32[8] = 3.242736;
+    data->data.F32[9] = 3.122204;
+    data->data.F32[10] = 2.837632;
+    data->data.F32[11] = 2.534700;
+    data->data.F32[12] = 2.439173;
+    data->data.F32[13] = 2.380830;
+    data->data.F32[14] = 2.316090;
+    data->data.F32[15] = 2.060826;
+    data->data.F32[16] = 1.945679;
+    data->data.F32[17] = 1.914126;
+    data->data.F32[18] = 1.759509;
+    data->data.F32[19] = 1.665067;
+    data->data.F32[20] = 1.737926;
+    data->data.F32[21] = 1.575523;
+    data->data.F32[22] = 1.525066;
+    data->data.F32[23] = 1.409607;
+    data->data.F32[24] = 1.395209;
+    data->data.F32[25] = 1.416887;
+    data->data.F32[26] = 1.376042;
+    data->data.F32[27] = 1.260955;
+    data->data.F32[28] = 1.289627;
+    data->data.F32[29] = 1.422672;
+    data->data.F32[30] = 1.228287;
+    data->data.F32[31] = 1.199176;
+    data->data.F32[32] = 1.189989;
+    data->data.F32[33] = 0.930076;
+    data->data.F32[34] = 1.224608;
+    data->data.F32[35] = 1.147376;
+    data->data.F32[36] = 1.114001;
+    data->data.F32[37] = 1.195118;
+    data->data.F32[38] = 1.269581;
+    data->data.F32[39] = 1.061982;
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psMinimizeChi2(): no masks");
+
+    theParams = psMinimizeChi2(myFunc,
+                               myFuncDeriv,
+                               domain,
+                               data,
+                               errors,
+                               initialGuess,
+                               NULL,
+                               &chiSq);
+
+    for (i=0;i<NUM_PARAMS;i++) {
+        printf("theParams[%d] is %.1f\n", i, theParams->data.F32[i]);
+    }
+    printf("chiSq is %f\n", chiSq);
+
+    psMemCheckCorruption(1);
+    printFooter(stdout,
+                "psMinimize functions",
+                "psMinimizeChi2(): no masks",
+                testStatus);
+    psMemCheckCorruption(1);
+    psFree(domain);
+    psFree(data);
+    psFree(errors);
+    psFree(initialGuess);
+    psFree(paramMask);
+    psFree(tmpVecPtr);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMinimize02.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMinimize02.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMinimize02.c	(revision 2163)
@@ -0,0 +1,168 @@
+/*****************************************************************************
+    This routine must ensure that the psMinimize function correctly
+    minimizes an arbitrary function.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psVector.h"
+#include "psImage.h"
+#include "psFunctions.h"
+#include "psMinimize.h"
+#include <math.h>
+#define DATA_WIDTH 2
+#define NUM_PARAMS 2
+
+float myFunc0(const psVector *restrict myParams,
+              const psVector *restrict myCoords)
+{
+    float P0 = myCoords->data.F32[0];
+    float P1 = myCoords->data.F32[1];
+    float x = myParams->data.F32[0];
+    float y = myParams->data.F32[1];
+    float tmp = 0.0;
+
+    tmp = 10.0 * (x - P0) * (x - P0) + 20.0 * (y - P1) * (y - P1) + 30.0;
+    //    printf("--------- myFunc((%.1f %.1f) %.1f %.1f) is %.1f ---------\n",
+    //    printf("--------- myFunc() params: (%.1f %.1f) coords: (%.1f %.1f) is %.1f ---------\n",
+    //           x, y, P0, P1, tmp);
+
+    return(tmp);
+}
+
+float myFuncDeriv0(const psVector *restrict myParams,
+                   const psVector *restrict myCoords,
+                   int whichParamDeriv)
+{
+    float P0 = myCoords->data.F32[0];
+    float P1 = myCoords->data.F32[1];
+    float x = myParams->data.F32[0];
+    float y = myParams->data.F32[1];
+    float tmp = 0.0;
+
+    if (whichParamDeriv == 0) {
+        tmp = 20.0 * (x - P0);
+    } else
+        if (whichParamDeriv == 1) {
+            tmp = 40.0 * (y - P1);
+        }
+
+    //    printf("--------- myFuncDeriv((%.1f %.1f) %.1f %.1f (%d)) is %.1f ---------\n",
+    //            x, y, myParams->data.F32[0], myParams->data.F32[1], whichParamDeriv, tmp);
+    return(tmp);
+}
+
+
+float myFunc(const psVector *restrict myParams,
+             const psVector *restrict myCoords)
+{
+    float x = myCoords->data.F32[0];
+    float y = myCoords->data.F32[1];
+    float A = myParams->data.F32[0];
+    float B = myParams->data.F32[1];
+    float C = myParams->data.F32[2];
+    float D = myParams->data.F32[3];
+    float tmp = 0.0;
+
+    tmp = (A * x) + (B*x*x) + (C*y*y) + (D*x*x*y);
+    printf("--------- myFunc((%.1f %.1f) %.1f %.1f %.1f %.1f) is %.1f ---------\n",
+           x, y, A, B, C, D, tmp);
+
+    return(tmp);
+}
+
+float myFuncDeriv(const psVector *restrict myParams,
+                  const psVector *restrict myCoords,
+                  int whichParamDeriv)
+{
+    float x = myCoords->data.F32[0];
+    float y = myCoords->data.F32[1];
+    float tmp = 0.0;
+
+    if (whichParamDeriv == 0) {
+        tmp = 1.0;
+        tmp = x;
+    } else
+        if (whichParamDeriv == 1) {
+            tmp = x;
+            tmp = x*x;
+        } else
+            if (whichParamDeriv == 2) {
+                tmp = y;
+                tmp = y*y;
+            } else
+                if (whichParamDeriv == 3) {
+                    tmp = x * x * y;
+                }
+
+    printf("--------- myFuncDeriv((%.1f %.1f) %.1f %.1f %.1f %.1f (%d)) is %.1f ---------\n",
+           x, y, myParams->data.F32[0], myParams->data.F32[1],
+           myParams->data.F32[2], myParams->data.F32[3], whichParamDeriv, tmp);
+    return(tmp);
+}
+
+
+int main()
+{
+    psVector *initialGuess = NULL;
+    psVector *paramMask = NULL;
+    psVector *coord = NULL;
+    int i = 0;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+    psVector *theParams = NULL;
+
+    initialGuess = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    paramMask = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    coord = psVectorAlloc(DATA_WIDTH, PS_TYPE_F32);
+
+
+    //--------- myFunc((0.0 1.0) -8.6 -7.6 14.6 5.0) is 6.0 ---------
+
+    // Build the data.
+    initialGuess->data.F32[0] = 5.0;
+    initialGuess->data.F32[1] = 7.0;
+
+    for (i=0;i<DATA_WIDTH;i++) {
+        coord->data.F32[i] = (float) i;
+    }
+    coord->data.F32[0] = 1.0;
+    coord->data.F32[1] = 2.0;
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psMinimize(): no masks");
+
+    for (i=0;i<NUM_PARAMS;i++)
+        printf("Initial parameter %d is: %.1f\n", i, initialGuess->data.F32[i]);
+
+    theParams = psMinimize(initialGuess,
+                           myFunc0,
+                           myFuncDeriv0,
+                           coord,
+                           NULL);
+
+    for (i=0;i<NUM_PARAMS;i++)
+        printf("Parameter %d is: %.1f\n", i, theParams->data.F32[i]);
+
+    psMemCheckCorruption(1);
+    printFooter(stdout,
+                "psMinimize functions",
+                "psMinimize(): no masks",
+                testStatus);
+
+    psMemCheckCorruption(1);
+    psFree(initialGuess);
+    psFree(paramMask);
+    psFree(coord);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMinimize03.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMinimize03.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMinimize03.c	(revision 2163)
@@ -0,0 +1,172 @@
+/*****************************************************************************
+    This routine must ensure that the psMinimize function correctly
+    minimizes an arbitrary function.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psVector.h"
+#include "psImage.h"
+#include "psFunctions.h"
+#include "psMinimize.h"
+#include <math.h>
+#define DATA_WIDTH 2
+#define NUM_PARAMS 4
+
+float myFunc0(const psVector *restrict myParams,
+              const psVector *restrict myCoords)
+{
+    float P0 = myCoords->data.F32[0];
+    float P1 = myCoords->data.F32[1];
+    float x = myParams->data.F32[0];
+    float y = myParams->data.F32[1];
+    float tmp = 0.0;
+
+    tmp = 10.0 * (x - P0) * (x - P0) + 20.0 * (y - P1) * (y - P1) + 30.0;
+    //    printf("--------- myFunc((%.1f %.1f) %.1f %.1f) is %.1f ---------\n",
+    //    printf("--------- myFunc() params: (%.1f %.1f) coords: (%.1f %.1f) is %.1f ---------\n",
+    //           x, y, P0, P1, tmp);
+
+    return(tmp);
+}
+
+float myFuncDeriv0(const psVector *restrict myParams,
+                   const psVector *restrict myCoords,
+                   int whichParamDeriv)
+{
+    float P0 = myCoords->data.F32[0];
+    float P1 = myCoords->data.F32[1];
+    float x = myParams->data.F32[0];
+    float y = myParams->data.F32[1];
+    float tmp = 0.0;
+
+    if (whichParamDeriv == 0) {
+        tmp = 20.0 * (x - P0);
+    } else
+        if (whichParamDeriv == 1) {
+            tmp = 40.0 * (y - P1);
+        }
+
+    //    printf("--------- myFuncDeriv((%.1f %.1f) %.1f %.1f (%d)) is %.1f ---------\n",
+    //            x, y, myParams->data.F32[0], myParams->data.F32[1], whichParamDeriv, tmp);
+    return(tmp);
+}
+
+
+float myFunc(const psVector *restrict myParams,
+             const psVector *restrict myCoords)
+{
+    float x = myCoords->data.F32[0];
+    float y = myCoords->data.F32[1];
+    float A = myParams->data.F32[0];
+    float B = myParams->data.F32[1];
+    float C = myParams->data.F32[2];
+    float D = myParams->data.F32[3];
+    float tmp = 0.0;
+
+    tmp = (A * x) + (B*x*x) + (C*y*y) + (D*x*x*y);
+    printf("-- myFunc() params: (%.1f %.1f %.1f %.1f) coords: (%.1f %.1f) is %.1f ---------\n",
+           A, B, C, D, x, y, tmp);
+
+    return(tmp);
+}
+
+float myFuncDeriv(const psVector *restrict myParams,
+                  const psVector *restrict myCoords,
+                  int whichParamDeriv)
+{
+    float x = myCoords->data.F32[0];
+    float y = myCoords->data.F32[1];
+    float tmp = 0.0;
+
+    if (whichParamDeriv == 0) {
+        tmp = 1.0;
+        tmp = x;
+    } else
+        if (whichParamDeriv == 1) {
+            tmp = x;
+            tmp = x*x;
+        } else
+            if (whichParamDeriv == 2) {
+                tmp = y;
+                tmp = y*y;
+            } else
+                if (whichParamDeriv == 3) {
+                    tmp = x * x * y;
+                }
+
+    printf("--------- myFuncDeriv((%.1f %.1f) %.1f %.1f %.1f %.1f (%d)) is %.1f ---------\n",
+           x, y, myParams->data.F32[0], myParams->data.F32[1],
+           myParams->data.F32[2], myParams->data.F32[3], whichParamDeriv, tmp);
+    return(tmp);
+}
+
+
+int main()
+{
+    psVector *initialGuess = NULL;
+    psVector *paramMask = NULL;
+    psVector *coord = NULL;
+    int i = 0;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+    psVector *theParams = NULL;
+
+    initialGuess = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    paramMask = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    coord = psVectorAlloc(DATA_WIDTH, PS_TYPE_F32);
+
+
+    //--------- myFunc((0.0 1.0) -8.6 -7.6 14.6 5.0) is 6.0 ---------
+
+    // Build the data.
+    initialGuess->data.F32[0] = 2.0;
+    initialGuess->data.F32[1] = 3.0;
+    initialGuess->data.F32[2] = 4.0;
+    initialGuess->data.F32[3] = 5.0;
+
+    for (i=0;i<DATA_WIDTH;i++) {
+        coord->data.F32[i] = (float) i;
+    }
+    coord->data.F32[0] = 1.0;
+    coord->data.F32[1] = 2.0;
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psMinimize(): no masks");
+
+    for (i=0;i<NUM_PARAMS;i++)
+        printf("Initial parameter %d is: %.1f\n", i, initialGuess->data.F32[i]);
+
+    theParams = psMinimize(initialGuess,
+                           myFunc,
+                           myFuncDeriv,
+                           coord,
+                           NULL);
+
+    for (i=0;i<NUM_PARAMS;i++)
+        printf("Parameter %d is: %.1f\n", i, theParams->data.F32[i]);
+
+    printf("Function is %.1f\n", myFunc(theParams, coord));
+
+    psMemCheckCorruption(1);
+    printFooter(stdout,
+                "psMinimize functions",
+                "psMinimize(): no masks",
+                testStatus);
+
+    psMemCheckCorruption(1);
+    psFree(initialGuess);
+    psFree(paramMask);
+    psFree(coord);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMinimize04.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMinimize04.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMinimize04.c	(revision 2163)
@@ -0,0 +1,265 @@
+/*****************************************************************************
+This routine must ensure that the psVectorFitPolynomial1D works correctly.
+We create a vectors of data points (x and y), and populate them with the
+values from an arbitrary function setData().  We then call
+psVectorFitPolynomial1D() with a regular polynomial data structure.  We then
+evaluate the polynomial with the coefficients generated above and determine
+if they are within an error tolerance of the expected values.
+ 
+    t00(): all input vectors are non-NULL.
+    t01(): yErr is NULL.
+    t02(): x, yErr is NULL.
+    t03(): x, y, yErr is NULL.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psVector.h"
+#include "psImage.h"
+#include "psFunctions.h"
+#include "psMinimize.h"
+#include <math.h>
+#define NUM_DATA 10
+#define POLY_ORDER 5
+#define A 3.0
+#define B 2.0
+#define C 3.0
+#define ERROR_TOLERANCE 0.10
+#define YERR 1.0
+double setData(double x)
+{
+    return(A + (B * x) + (C * x * x));
+}
+
+int t00()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    psVector *yErr = NULL;
+    int i = 0;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+    double expectData;
+    double actualData;
+
+    myPoly = psPolynomial1DAlloc(POLY_ORDER+1, PS_POLYNOMIAL_ORD);
+    x = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+    y = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+    yErr = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+
+    for (i=0;i<NUM_DATA;i++) {
+        x->data.F64[i] = (double) i;
+        y->data.F64[i] = setData(x->data.F64[i]);
+        yErr->data.F64[i] = YERR;
+        //        printf("Original data %d: (%.1f %.1f)\n", i, x->data.F64[i], y->data.F64[i]);
+    }
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): equal difference in variable yErr");
+
+    psVectorFitPolynomial1D(myPoly, x, y, yErr);
+
+    //    for (i=0;i<POLY_ORDER+1;i++) {
+    //        printf("Polynomial coefficient %d is %0.1f\n", i, myPoly->coeff[i]);
+    //    }
+
+    for (i=0;i<NUM_DATA;i++) {
+        expectData = setData(x->data.F64[i]);
+        actualData = psPolynomial1DEval(x->data.F64[i], myPoly);
+        if (fabs(actualData-expectData) > fabs(ERROR_TOLERANCE * expectData)) {
+            printf("ERROR: Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+                   i, x->data.F64[i], actualData, expectData);
+            testStatus = false;
+        }
+        //        } else {
+        //            printf("Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+        //                   i, x->data.F64[i], actualData, expectData);
+        //        }
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myPoly);
+    psFree(x);
+    psFree(y);
+    psFree(yErr);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): equal differences in variable yErr",
+                testStatus);
+
+    return (!testStatus);
+}
+
+int t01()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    int i = 0;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+    double expectData;
+    double actualData;
+
+    myPoly = psPolynomial1DAlloc(POLY_ORDER+1, PS_POLYNOMIAL_ORD);
+    x = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+    y = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+
+    for (i=0;i<NUM_DATA;i++) {
+        x->data.F64[i] = (double) i;
+        y->data.F64[i] = setData(x->data.F64[i]);
+        //        printf("Original data %d: (%.1f %.1f)\n", i, x->data.F64[i], y->data.F64[i]);
+    }
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): yErr is NULL");
+
+    psVectorFitPolynomial1D(myPoly, x, y, NULL);
+
+    //    for (i=0;i<POLY_ORDER+1;i++) {
+    //        printf("Polynomial coefficient %d is %0.1f\n", i, myPoly->coeff[i]);
+    //    }
+
+    for (i=0;i<NUM_DATA;i++) {
+        expectData = setData(x->data.F64[i]);
+        actualData = psPolynomial1DEval(x->data.F64[i], myPoly);
+        if (fabs(actualData-expectData) > fabs(ERROR_TOLERANCE * expectData)) {
+            printf("ERROR: Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+                   i, x->data.F64[i], actualData, expectData);
+            testStatus = false;
+            //        } else {
+            //            printf("Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+            //                   i, x->data.F64[i], actualData, expectData);
+        }
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myPoly);
+    psFree(x);
+    psFree(y);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): yErr is NULL",
+                testStatus);
+
+    return (!testStatus);
+}
+
+int t02()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *y = NULL;
+    int i = 0;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+    double expectData;
+    double actualData;
+
+    myPoly = psPolynomial1DAlloc(POLY_ORDER+1, PS_POLYNOMIAL_ORD);
+    y = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+
+    for (i=0;i<NUM_DATA;i++) {
+        y->data.F64[i] = setData((double) i);
+        //        printf("Original data %d: (%.1f)\n", i, y->data.F64[i]);
+    }
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): x, yErr is NULL");
+
+    psVectorFitPolynomial1D(myPoly, NULL, y, NULL);
+
+    //    for (i=0;i<POLY_ORDER+1;i++) {
+    //        printf("Polynomial coefficient %d is %0.1f\n", i, myPoly->coeff[i]);
+    //    }
+
+    for (i=0;i<NUM_DATA;i++) {
+        expectData = setData((double) i);
+        actualData = psPolynomial1DEval((double) i, myPoly);
+        if (fabs(actualData-expectData) > fabs(ERROR_TOLERANCE * expectData)) {
+            printf("ERROR: Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+                   i, (double) i, actualData, expectData);
+            testStatus = false;
+            //        } else {
+            //            printf("Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+            //                   i, (double) i, actualData, expectData);
+        }
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myPoly);
+    psFree(y);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): x, yErr is NULL",
+                testStatus);
+
+    return (!testStatus);
+}
+
+int t03()
+{
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+    psPolynomial1D *myPoly = NULL;
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): all inputs are NULL");
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error for null input polynomial.");
+    myPoly = psVectorFitPolynomial1D(NULL, NULL, NULL, NULL);
+    if ( myPoly != NULL ) {
+        psError(__func__,"A null polynomial should have returned a null pointer.");
+        testStatus = false;
+    }
+
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): all inputs are NULL",
+                testStatus);
+
+    return (!testStatus);
+}
+
+
+int main()
+{
+    t00();
+    t01();
+    t02();
+    t03();
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMinimize04_F32.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMinimize04_F32.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMinimize04_F32.c	(revision 2163)
@@ -0,0 +1,259 @@
+/*****************************************************************************
+This routine must ensure that the psVectorFitPolynomial1D works correctly.
+We create a vectors of data points (x and y), and populate them with the
+values from an arbitrary function setData().  We then call
+psVectorFitPolynomial1D() with a regular polynomial data structure.  We then
+evaluate the polynomial with the coefficients generated above and determine
+if they are within an error tolerance of the expected values.
+ 
+    t00(): all input vectors are non-NULL.
+    t01(): yErr is NULL.
+    t02(): x, yErr is NULL.
+    t03(): x, y, yErr is NULL.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psVector.h"
+#include "psImage.h"
+#include "psFunctions.h"
+#include "psMinimize.h"
+#include <math.h>
+#define NUM_DATA 10
+#define POLY_ORDER 5
+#define A 3.0
+#define B 2.0
+#define C 3.0
+#define ERROR_TOLERANCE 0.10
+#define YERR 10.0
+float setData(float x)
+{
+    return(A + (B * x) + (C * x * x));
+}
+
+int t00()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    psVector *yErr = NULL;
+    int i = 0;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+    float expectData;
+    float actualData;
+
+    myPoly = psPolynomial1DAlloc(POLY_ORDER+1, PS_POLYNOMIAL_ORD);
+    x = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+    y = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+    yErr = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+
+    for (i=0;i<NUM_DATA;i++) {
+        x->data.F32[i] = (float) i;
+        y->data.F32[i] = setData(x->data.F32[i]);
+        yErr->data.F32[i] = YERR;
+        //        printf("Original data %d: (%.1f %.1f)\n", i, x->data.F32[i], y->data.F32[i]);
+    }
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): equal errors in yErr");
+
+    psVectorFitPolynomial1D(myPoly, x, y, yErr);
+
+    //    for (i=0;i<POLY_ORDER+1;i++) {
+    //        printf("Polynomial coefficient %d is %0.1f\n", i, myPoly->coeff[i]);
+    //    }
+
+    for (i=0;i<NUM_DATA;i++) {
+        expectData = setData(x->data.F32[i]);
+        actualData = psPolynomial1DEval(x->data.F32[i], myPoly);
+        if (fabs(actualData-expectData) > fabs(ERROR_TOLERANCE * expectData)) {
+            printf("ERROR: Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+                   i, x->data.F32[i], actualData, expectData);
+            testStatus = false;
+            //        } else {
+            //            printf("Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+            //                   i, x->data.F32[i], actualData, expectData);
+        }
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myPoly);
+    psFree(x);
+    psFree(y);
+    psFree(yErr);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): equal errors in yErr",
+                testStatus);
+
+    return (!testStatus);
+}
+
+int t01()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    int i = 0;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+    float expectData;
+    float actualData;
+
+    myPoly = psPolynomial1DAlloc(POLY_ORDER+1, PS_POLYNOMIAL_ORD);
+    x = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+    y = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+
+    for (i=0;i<NUM_DATA;i++) {
+        x->data.F32[i] = (float) i;
+        y->data.F32[i] = setData(x->data.F32[i]);
+        //        printf("Original data %d: (%.1f %.1f)\n", i, x->data.F32[i], y->data.F32[i]);
+    }
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): yErr is NULL");
+
+    psVectorFitPolynomial1D(myPoly, x, y, NULL);
+
+    //    for (i=0;i<POLY_ORDER+1;i++) {
+    //        printf("Polynomial coefficient %d is %0.1f\n", i, myPoly->coeff[i]);
+    //    }
+
+    for (i=0;i<NUM_DATA;i++) {
+        expectData = setData(x->data.F32[i]);
+        actualData = psPolynomial1DEval(x->data.F32[i], myPoly);
+        if (fabs(actualData-expectData) > fabs(ERROR_TOLERANCE * expectData)) {
+            printf("ERROR: Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+                   i, x->data.F32[i], actualData, expectData);
+            testStatus = false;
+            //        } else {
+            //            printf("Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+            //                   i, x->data.F32[i], actualData, expectData);
+        }
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myPoly);
+    psFree(x);
+    psFree(y);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): yErr is NULL",
+                testStatus);
+
+    return (!testStatus);
+}
+
+int t02()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *y = NULL;
+    int i = 0;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+    float expectData;
+    float actualData;
+
+    myPoly = psPolynomial1DAlloc(POLY_ORDER+1, PS_POLYNOMIAL_ORD);
+    y = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+
+    for (i=0;i<NUM_DATA;i++) {
+        y->data.F32[i] = setData((float) i);
+        //        printf("Original data %d: (%.1f)\n", i, y->data.F32[i]);
+    }
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): x, yErr is NULL");
+
+    psVectorFitPolynomial1D(myPoly, NULL, y, NULL);
+
+    //    for (i=0;i<POLY_ORDER+1;i++) {
+    //        printf("Polynomial coefficient %d is %0.1f\n", i, myPoly->coeff[i]);
+    //    }
+
+    for (i=0;i<NUM_DATA;i++) {
+        expectData = setData((float) i);
+        actualData = psPolynomial1DEval((float) i, myPoly);
+        if (fabs(actualData-expectData) > fabs(ERROR_TOLERANCE * expectData)) {
+            printf("ERROR: Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+                   i, (float) i, actualData, expectData);
+            testStatus = false;
+            //        } else {
+            //            printf("Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+            //                   i, (float) i, actualData, expectData);
+        }
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myPoly);
+    psFree(y);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): x, yErr is NULL",
+                testStatus);
+
+    return (!testStatus);
+}
+
+int t03()
+{
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): all inputs are NULL");
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate error for null arguments.");
+    psVectorFitPolynomial1D(NULL, NULL, NULL, NULL);
+
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): all inputs are NULL",
+                testStatus);
+
+    return (!testStatus);
+}
+
+
+int main()
+{
+    t00();
+    t01();
+    t02();
+    t03();
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMinimize04b.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMinimize04b.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMinimize04b.c	(revision 2163)
@@ -0,0 +1,252 @@
+/*****************************************************************************
+    This routine must ensure that the psVectorFitPolynomial1D works correctly.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psVector.h"
+#include "psImage.h"
+#include "psFunctions.h"
+#include "psMinimize.h"
+#include <math.h>
+#define NUM_DATA 20
+#define POLY_ORDER 10
+#define A 2.0
+#define B 3.0
+#define C 2.0
+#define D 4.0
+#define E 5.0
+#define ERROR_TOLERANCE 0.10
+#define IGNORE (ERROR_TOLERANCE * NUM_DATA)
+
+double setData(double x)
+{
+    return(A + (B * x) + (C * x * x) + (D * x * x * x) + (E * x * x * x * x));
+}
+
+int t00()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    psVector *yErr = NULL;
+    int i = 0;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+
+    myPoly = psPolynomial1DAlloc(POLY_ORDER+1, PS_POLYNOMIAL_CHEB);
+    x = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+    y = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+    yErr = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+
+    for (i=0;i<NUM_DATA;i++) {
+        x->data.F64[i] = (double) i;
+        y->data.F64[i] = setData(x->data.F64[i]);
+        yErr->data.F64[i] = 1.0;
+    }
+    p_psNormalizeVectorF64(x);
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): CHEB, equal errors in yErr");
+
+    psVectorFitPolynomial1D(myPoly, x, y, yErr);
+
+    //  Remove for testing since print out differs from platforms
+    //    for (i=0;i<POLY_ORDER+1;i++) {
+    //        printf("Polynomial coefficient %d is %0.1f\n", i, myPoly->coeff[i]);
+    //    }
+
+    // We don't test the first or last few data items.
+    for (i=IGNORE;i<NUM_DATA-IGNORE;i++) {
+        double expectData = y->data.F64[i];
+        double actualData = psPolynomial1DEval(x->data.F64[i], myPoly);
+        if (fabs(actualData-expectData) > fabs(ERROR_TOLERANCE * expectData)) {
+            printf("ERROR: Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+                   i, x->data.F64[i], actualData, expectData);
+            testStatus = false;
+        }
+        //      Remove for testing since print out differs from platforms
+        //        } else {
+        //            printf("Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+        //                   i, x->data.F64[i], actualData, expectData);
+        //        }
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myPoly);
+    psFree(x);
+    psFree(y);
+    psFree(yErr);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): CHEB, equal errors in yErr",
+                testStatus);
+    return (!testStatus);
+}
+
+
+int t01()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    int i = 0;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+
+    myPoly = psPolynomial1DAlloc(POLY_ORDER+1, PS_POLYNOMIAL_CHEB);
+    x = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+    y = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+
+    for (i=0;i<NUM_DATA;i++) {
+        x->data.F64[i] = (double) i;
+        y->data.F64[i] = setData(x->data.F64[i]);
+    }
+    p_psNormalizeVectorF64(x);
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): CHEB, yErr is NULL");
+
+    psVectorFitPolynomial1D(myPoly, x, y, NULL);
+
+    // We don't test the first or last few data items.
+    for (i=IGNORE;i<NUM_DATA-IGNORE;i++) {
+        double expectData = y->data.F64[i];
+        double actualData = psPolynomial1DEval(x->data.F64[i], myPoly);
+        if (fabs(actualData-expectData) > fabs(ERROR_TOLERANCE * expectData)) {
+            printf("ERROR: Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+                   i, x->data.F64[i], actualData, expectData);
+            testStatus = false;
+        }
+        //      Remove for testing since print out differs from platforms
+        //        } else {
+        //            printf("Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+        //                   i, x->data.F64[i], actualData, expectData);
+        //        }
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myPoly);
+    psFree(x);
+    psFree(y);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): CHEB, yErr is NULL",
+                testStatus);
+    return (!testStatus);
+}
+
+
+int t02()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    int i = 0;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+
+    myPoly = psPolynomial1DAlloc(POLY_ORDER+1, PS_POLYNOMIAL_CHEB);
+    x = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+    y = psVectorAlloc(NUM_DATA, PS_TYPE_F64);
+
+    for (i=0;i<NUM_DATA;i++) {
+        x->data.F64[i] = (double) i;
+        y->data.F64[i] = setData(x->data.F64[i]);
+    }
+    p_psNormalizeVectorF64(x);
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): CHEB, x, yErr is NULL");
+
+    psVectorFitPolynomial1D(myPoly, NULL, y, NULL);
+
+    // We don't test the first or last few data items.
+    for (i=IGNORE;i<NUM_DATA-IGNORE;i++) {
+        double expectData = y->data.F64[i];
+        double actualData = psPolynomial1DEval(x->data.F64[i], myPoly);
+        if (fabs(actualData-expectData) > fabs(ERROR_TOLERANCE * expectData)) {
+            printf("ERROR: Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+                   i, x->data.F64[i], actualData, expectData);
+            testStatus = false;
+        }
+        //      Remove for testing since print out differs from platforms
+        //        } else {
+        //            printf("Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+        //                   i, x->data.F64[i], actualData, expectData);
+        //        }
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myPoly);
+    psFree(x);
+    psFree(y);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): CHEB, x, yErr is NULL",
+                testStatus);
+    return (!testStatus);
+}
+
+int t03()
+{
+    psPolynomial1D *myPoly = NULL;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): CHEB, yErr is NULL");
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error for null arguments.");
+    myPoly = psVectorFitPolynomial1D(NULL, NULL, NULL, NULL);
+    if (myPoly != NULL) {
+        printf("ERROR: psVectorFitPolynomial1D() returned a non-NULL polynomial.\n");
+        testStatus = false;
+    }
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): CHEB, yErr is NULL",
+                testStatus);
+    return (!testStatus);
+}
+
+int main()
+{
+    t00();
+    t01();
+    t02();
+    t03();
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMinimize04b_F32.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMinimize04b_F32.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMinimize04b_F32.c	(revision 2163)
@@ -0,0 +1,252 @@
+/*****************************************************************************
+    This routine must ensure that the psVectorFitPolynomial1D works correctly.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psVector.h"
+#include "psImage.h"
+#include "psFunctions.h"
+#include "psMinimize.h"
+#include <math.h>
+#define NUM_DATA 20
+#define POLY_ORDER 10
+#define A 2.0
+#define B 3.0
+#define C 2.0
+#define D 4.0
+#define E 5.0
+#define ERROR_TOLERANCE 0.10
+#define IGNORE (ERROR_TOLERANCE * NUM_DATA)
+
+float setData(float x)
+{
+    return(A + (B * x) + (C * x * x) + (D * x * x * x) + (E * x * x * x * x));
+}
+
+int t00()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    psVector *yErr = NULL;
+    int i = 0;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+
+    myPoly = psPolynomial1DAlloc(POLY_ORDER+1, PS_POLYNOMIAL_CHEB);
+    x = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+    y = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+    yErr = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+
+    for (i=0;i<NUM_DATA;i++) {
+        x->data.F32[i] = (float) i;
+        y->data.F32[i] = setData(x->data.F32[i]);
+        yErr->data.F32[i] = 1.0;
+    }
+    p_psNormalizeVector(x);
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): CHEB, equal errors in yErr");
+
+    psVectorFitPolynomial1D(myPoly, x, y, yErr);
+
+    //  Remove for testing since printout differs between platforms
+    //    for (i=0;i<POLY_ORDER+1;i++) {
+    //        printf("Polynomial coefficient %d is %0.1f\n", i, myPoly->coeff[i]);
+    //    }
+
+    // We don't test the first or last few data items.
+    for (i=IGNORE;i<NUM_DATA-IGNORE;i++) {
+        float expectData = y->data.F32[i];
+        float actualData = psPolynomial1DEval(x->data.F32[i], myPoly);
+        if (fabs(actualData-expectData) > fabs(ERROR_TOLERANCE * expectData)) {
+            printf("ERROR: Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+                   i, x->data.F32[i], actualData, expectData);
+            testStatus = false;
+        }
+        //       REMOVE for testing since printout is different for different platforms
+        //        } else {
+        //            printf("Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+        //                   i, x->data.F32[i], actualData, expectData);
+        //        }
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myPoly);
+    psFree(x);
+    psFree(y);
+    psFree(yErr);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): CHEB, equal errors in yErr",
+                testStatus);
+    return (!testStatus);
+}
+
+
+int t01()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    int i = 0;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+
+    myPoly = psPolynomial1DAlloc(POLY_ORDER+1, PS_POLYNOMIAL_CHEB);
+    x = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+    y = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+
+    for (i=0;i<NUM_DATA;i++) {
+        x->data.F32[i] = (float) i;
+        y->data.F32[i] = setData(x->data.F32[i]);
+    }
+    p_psNormalizeVector(x);
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): CHEB, yErr is NULL");
+
+    psVectorFitPolynomial1D(myPoly, x, y, NULL);
+
+    // We don't test the first or last few data items.
+    for (i=IGNORE;i<NUM_DATA-IGNORE;i++) {
+        float expectData = y->data.F32[i];
+        float actualData = psPolynomial1DEval(x->data.F32[i], myPoly);
+        if (fabs(actualData-expectData) > fabs(ERROR_TOLERANCE * expectData)) {
+            printf("ERROR: Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+                   i, x->data.F32[i], actualData, expectData);
+            testStatus = false;
+        }
+        //      Removed for testing since printout different on different platforms
+        //        } else {
+        //            printf("Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+        //                   i, x->data.F32[i], actualData, expectData);
+        //        }
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myPoly);
+    psFree(x);
+    psFree(y);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): CHEB, yErr is NULL",
+                testStatus);
+    return (!testStatus);
+}
+
+
+int t02()
+{
+    psPolynomial1D *myPoly = NULL;
+    psVector *x = NULL;
+    psVector *y = NULL;
+    int i = 0;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+
+    myPoly = psPolynomial1DAlloc(POLY_ORDER+1, PS_POLYNOMIAL_CHEB);
+    x = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+    y = psVectorAlloc(NUM_DATA, PS_TYPE_F32);
+
+    for (i=0;i<NUM_DATA;i++) {
+        x->data.F32[i] = (float) i;
+        y->data.F32[i] = setData(x->data.F32[i]);
+    }
+    p_psNormalizeVector(x);
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): CHEB, x, yErr is NULL");
+
+    psVectorFitPolynomial1D(myPoly, NULL, y, NULL);
+
+    // We don't test the first or last few data items.
+    for (i=IGNORE;i<NUM_DATA-IGNORE;i++) {
+        float expectData = y->data.F32[i];
+        float  actualData = psPolynomial1DEval(x->data.F32[i], myPoly);
+        if (fabs(actualData-expectData) > fabs(ERROR_TOLERANCE * expectData)) {
+            printf("ERROR: Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+                   i, x->data.F32[i], actualData, expectData);
+            testStatus = false;
+        }
+        //      Remove for testing since printout different for different platforms
+        //        } else {
+        //            printf("Fitted data %d: (%.1f %.1f), expected was (%.1f)\n",
+        //                   i, x->data.F32[i], actualData, expectData);
+        //        }
+    }
+
+    psMemCheckCorruption(1);
+    psFree(myPoly);
+    psFree(x);
+    psFree(y);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): CHEB, x, yErr is NULL",
+                testStatus);
+    return (!testStatus);
+}
+
+int t03()
+{
+    psPolynomial1D *myPoly = NULL;
+    int currentId = psMemGetId();
+    int testStatus = true;
+    int memLeaks = 0;
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psVectorFitPolynomial1D(): CHEB, yErr is NULL");
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate error for null arguments.");
+    myPoly = psVectorFitPolynomial1D(NULL, NULL, NULL, NULL);
+    if (myPoly != NULL) {
+        printf("ERROR: psVectorFitPolynomial1D() returned a non-NULL polynomial.\n");
+        testStatus = false;
+    }
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psMinimize functions",
+                "psVectorFitPolynomial1D(): CHEB, yErr is NULL",
+                testStatus);
+    return (!testStatus);
+}
+
+int main()
+{
+    t00();
+    t01();
+    t02();
+    t03();
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMinimize05.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMinimize05.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMinimize05.c	(revision 2163)
@@ -0,0 +1,276 @@
+/*****************************************************************************
+    This routine must ensure that psMinimizePowell() works correctly.
+ 
+    We test with a NULL and non-NULL paramMask.
+ 
+    XXX: Must verify the stderr for the NULL parameter tests.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include <math.h>
+#define N 5
+#define MIN_VALUE 20.0
+#define NUM_PARAMS 10
+#define ERROR_TOLERANCE 0.10
+float expectedParm[NUM_PARAMS];
+int testStatus = true;
+
+/*****************************************************************************
+myFunc(): This routine subtracts the associate value in expectedParm[] from
+each parameter and then squares it, then sums that for all parameters, then
+adds MIN_VALUE to it.  The minimum for this function will be MIN_VALUE, and
+will occur when each parameter equals the associated value in expectedParm[].
+ 
+This procedure ignores the coordinates, other than to ensure that they were
+passed correctly from psMinimizePowell().
+ *****************************************************************************/
+float myFunc(psVector *myParams,
+             psArray *myCoords)
+{
+    float sum = 0.0;
+    float coordData = 0.0;
+    float expData = 0.0;
+    int i;
+
+    for (i=0;i<N;i++) {
+        coordData = ((psVector *) (myCoords->data[i]))->data.F32[0];
+        expData = (float) (i+10);
+        if (fabs(coordData - expData) > FLT_EPSILON) {
+            printf("ERROR(1): coordinate data was incorrectly passed to myFunc()\n");
+            printf("ERROR(1): was (%f) should be (%f)\n", coordData, expData);
+            testStatus = false;
+        }
+        coordData = ((psVector *) (myCoords->data[i]))->data.F32[1];
+        expData = (float) (i+3);
+        if (fabs(coordData - expData) > FLT_EPSILON) {
+            printf("ERROR(2): coordinate data was incorrectly passed to myFunc()\n");
+            printf("ERROR(2): was (%f) should be (%f)\n", coordData, expData);
+            testStatus = false;
+        }
+    }
+
+
+    sum = 0.0;
+    for (i=0;i<NUM_PARAMS;i++) {
+        sum+= (myParams->data.F32[i] - expectedParm[i]) * (myParams->data.F32[i] - expectedParm[i]);
+    }
+    sum = MIN_VALUE + (sum * sum);
+
+    return(sum);
+}
+
+
+int t00()
+{
+    int currentId = psMemGetId();
+    int memLeaks = 0;
+    int i = 0;
+    psArray *myCoords;
+    psVector *myParams;
+    psVector *myParamMask;
+    psMinimization *min;
+
+    psTraceSetLevel(".psLib", 0);
+    /**************************************************************************
+     *************************************************************************/
+    myParams = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    myParamMask = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    min = psMinimizationAlloc(100, 0.01);
+
+    myCoords = psArrayAlloc(N);
+    for (i=0;i<N;i++) {
+        myCoords->data[i] = (psPTR *) psVectorAlloc(2, PS_TYPE_F32);
+        ((psVector *) (myCoords->data[i]))->data.F32[0] = (float) (i+10);
+        ((psVector *) (myCoords->data[i]))->data.F32[1] = (float) (i+3);
+    }
+    for (i=0;i<NUM_PARAMS;i++) {
+        expectedParm[i] = 2.32 + (float) (2 * i);
+        myParams->data.F32[i] = 0.0;
+        myParamMask->data.U8[i] = 0;
+    }
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psMinimizePowell()");
+
+    psMinimizePowell(min,
+                     myParams,
+                     myParamMask,
+                     myCoords,
+                     (psMinimizePowellFunc) myFunc);
+
+    printf("\nThe minimum is %f (expected: %f)\n", min->value, MIN_VALUE);
+
+    for (i=0;i<NUM_PARAMS;i++) {
+        printf("Parameter %d at the minimum is %f (expected: %f)\n", i,
+               myParams->data.F32[i], expectedParm[i]);
+
+        if (fabs(myParams->data.F32[i] - expectedParm[i]) > fabs(ERROR_TOLERANCE * expectedParm[i])) {
+            printf("ERROR: Parameter %d: (%.1f), expected was (%.1f)\n",
+                   i, myParams->data.F32[i], expectedParm[i]);
+            testStatus = false;
+        } else {
+            printf("Parameter %d: (%.1f), expected was (%.1f)\n",
+                   i, myParams->data.F32[i], expectedParm[i]);
+        }
+    }
+
+
+    psFree(myCoords);
+    psFree(myParams);
+    psFree(myParamMask);
+    psFree(min);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psMinimize functions",
+                "psMinimizePowell()",
+                testStatus);
+
+
+    return (!testStatus);
+}
+
+int t01()
+{
+    int currentId = psMemGetId();
+    int memLeaks = 0;
+    int i = 0;
+    psArray *myCoords;
+    psVector *myParams;
+    psMinimization *min;
+
+    psTraceSetLevel(".psLib", 0);
+    /**************************************************************************
+     *************************************************************************/
+    myParams = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    min = psMinimizationAlloc(100, 0.01);
+
+    myCoords = psArrayAlloc(N);
+    for (i=0;i<N;i++) {
+        myCoords->data[i] = (psPTR *) psVectorAlloc(2, PS_TYPE_F32);
+        ((psVector *) (myCoords->data[i]))->data.F32[0] = (float) (i+10);
+        ((psVector *) (myCoords->data[i]))->data.F32[1] = (float) (i+3);
+    }
+    for (i=0;i<NUM_PARAMS;i++) {
+        expectedParm[i] = 2.32 + (float) (2 * i);
+        myParams->data.F32[i] = 0.0;
+    }
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psMinimizePowell()");
+
+    psMinimizePowell(min,
+                     myParams,
+                     NULL,
+                     myCoords,
+                     (psMinimizePowellFunc) myFunc);
+
+    printf("\nThe minimum is %f (expected: %f)\n", min->value, MIN_VALUE);
+
+    for (i=0;i<NUM_PARAMS;i++) {
+        printf("Parameter %d at the minimum is %f (expected: %f)\n", i,
+               myParams->data.F32[i], expectedParm[i]);
+
+        if (fabs(myParams->data.F32[i] - expectedParm[i]) > fabs(ERROR_TOLERANCE * expectedParm[i])) {
+            printf("ERROR: Parameter %d: (%.1f), expected was (%.1f)\n",
+                   i, myParams->data.F32[i], expectedParm[i]);
+            testStatus = false;
+        } else {
+            printf("Parameter %d: (%.1f), expected was (%.1f)\n",
+                   i, myParams->data.F32[i], expectedParm[i]);
+        }
+    }
+
+
+    psFree(myCoords);
+    psFree(myParams);
+    psFree(min);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psMinimize functions",
+                "psMinimizePowell()",
+                testStatus);
+
+
+    return (!testStatus);
+}
+
+int t02()
+{
+    int currentId = psMemGetId();
+    int memLeaks = 0;
+    int i = 0;
+    psArray *myCoords;
+    psVector *myParams;
+    psVector *myParamMask;
+    psMinimization *min;
+
+    psTraceSetLevel(".psLib", 0);
+    /**************************************************************************
+     *************************************************************************/
+    myParams = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    myParamMask = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    min = psMinimizationAlloc(100, 0.01);
+
+    myCoords = psArrayAlloc(N);
+    for (i=0;i<N;i++) {
+        myCoords->data[i] = (psPTR *) psVectorAlloc(2, PS_TYPE_F32);
+        ((psVector *) (myCoords->data[i]))->data.F32[0] = (float) (i+10);
+        ((psVector *) (myCoords->data[i]))->data.F32[1] = (float) (i+3);
+    }
+    for (i=0;i<NUM_PARAMS;i++) {
+        expectedParm[i] = 2.32 + (float) (2 * i);
+        myParams->data.F32[i] = 0.0;
+        myParamMask->data.U8[i] = 0;
+    }
+
+    printPositiveTestHeader(stdout,
+                            "psMinimize functions",
+                            "psMinimizePowell(): various NULL inputs");
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate error for null minimize.");
+    psMinimizePowell(NULL, myParams, myParamMask, myCoords, (psMinimizePowellFunc) myFunc);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate error for null parameter vector");
+    psMinimizePowell(min, NULL, myParamMask, myCoords,(psMinimizePowellFunc) myFunc);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate error for null coords.");
+    psMinimizePowell(min, myParams, myParamMask, NULL, (psMinimizePowellFunc) myFunc);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate error for null function");
+    psMinimizePowell(min, myParams, myParamMask, myCoords, NULL);
+
+    psFree(myCoords);
+    psFree(myParams);
+    psFree(myParamMask);
+    psFree(min);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    printFooter(stdout,
+                "psMinimize functions",
+                "psMinimizePowell(): various NULL inputs",
+                testStatus);
+
+
+    return (!testStatus);
+}
+
+int main()
+{
+    t00();
+    t01();
+    t02();
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psMinimize06.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psMinimize06.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psMinimize06.c	(revision 2163)
@@ -0,0 +1,143 @@
+/*****************************************************************************
+    This routine must ensure that psMinimizeLM() works correctly.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include <math.h>
+#define NUM_ITERATIONS 10000
+#define ERR_TOL 0.0
+#define N 5
+#define MIN_VALUE 5.0
+#define NUM_PARAMS 3
+float expectedParm[NUM_PARAMS];
+int testStatus = true;
+
+/*****************************************************************************
+myFunc(): This routine subtracts the associate value in expectedParm[] from
+each parameter and then squares it, then sums that for all parameters, then
+adds MIN_VALUE to it.  The minimum for this function will be MIN_VALUE, and
+will occur when each parameter equals the associated value in expectedParm[].
+ 
+This procedure ignores the coordinates, other than to ensure that they were
+passed correctly from psMinimizePowell().
+ 
+ *****************************************************************************/
+float myFunc(psVector *myDeriv,
+             psVector *myParams,
+             psVector *myCoords)
+{
+    float sum = 0.0;
+    //    float coordData = 0.0;
+    //    float expData = 0.0;
+    int i;
+
+    if (myDeriv == NULL) {
+        myDeriv = psVectorAlloc(myParams->n, PS_TYPE_F32);
+        psError(__func__, "myDeriv is NULL.\n");
+    }
+
+    // Simply test that coords were passed in correctly.
+    /*
+        for (i=0;i<N;i++) {
+            coordData = myCoords->data.F32[0];
+            expData = (float) (i+10);
+            if (fabs(coordData - expData) > FLT_EPSILON) {
+                printf("ERROR(1): coordinate data was incorrectly passed to myFunc()\n");
+                printf("ERROR(1): was (%f) should be (%f)\n", coordData, expData);
+                testStatus = false;
+            }
+            coordData = myCoords->data.F32[1];
+            expData = (float) (i+3);
+            if (fabs(coordData - expData) > FLT_EPSILON) {
+                printf("ERROR(2): coordinate data was incorrectly passed to myFunc()\n");
+                printf("ERROR(2): was (%f) should be (%f)\n", coordData, expData);
+                testStatus = false;
+            }
+        }
+    */
+
+    sum = 0.0;
+    for (i=0;i<NUM_PARAMS;i++) {
+        sum+= (myParams->data.F32[i] - expectedParm[i]) *
+              (myParams->data.F32[i] - expectedParm[i]);
+        myDeriv->data.F32[i] = (2.0 * myParams->data.F32[i]) -
+                               (2.0 * expectedParm[i]);
+    }
+    //    for (i=0;i<NUM_PARAMS;i++)
+    //        printf("HMMM: myParams->data.F32[%d] is %f\n", i, myParams->data.F32[i]);
+    //    for (i=0;i<NUM_PARAMS;i++)
+    //        printf("HMMM: myDeriv->data.F32[%d] is %f\n", i, myDeriv->data.F32[i]);
+
+    sum+= MIN_VALUE;
+    return(sum);
+}
+
+
+int main()
+{
+    int currentId = psMemGetId();
+    int memLeaks = 0;
+    int i = 0;
+    psArray *myCoords;
+    psVector *myParams;
+    psVector *myParamMask;
+    psImage *myCovar;
+    psMinimization *min;
+    psVector *x = psVectorAlloc(N, PS_TYPE_F32);
+    psVector *y = psVectorAlloc(N, PS_TYPE_F32);
+
+    psTraceSetLevel(".psLib", 0);
+    /**************************************************************************
+     *************************************************************************/
+    myParams = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    myParamMask = psVectorAlloc(NUM_PARAMS, PS_TYPE_F32);
+    min = psMinimizationAlloc(NUM_ITERATIONS, ERR_TOL);
+    myCovar = psImageAlloc(NUM_PARAMS, NUM_PARAMS, PS_TYPE_F32);
+
+    myCoords = psArrayAlloc(N);
+    for (i=0;i<N;i++) {
+        myCoords->data[i] = (psPTR *) psVectorAlloc(2, PS_TYPE_F32);
+        ((psVector *) (myCoords->data[i]))->data.F32[0] = (float) (i+10);
+        ((psVector *) (myCoords->data[i]))->data.F32[1] = (float) (i+3);
+        x->data.F32[i] = (float) i;
+        y->data.F32[i] = (float) i;
+    }
+    for (i=0;i<NUM_PARAMS;i++) {
+        expectedParm[i] = 2.42 + (float) (2 * i);
+        myParams->data.F32[i] = (float) i;
+        myParams->data.F32[i] = expectedParm[i] * 1.3;
+        myParams->data.F32[i] = (float) (5 + i);
+        myParams->data.F32[i] = 0.0;
+        myParamMask->data.U8[i] = 0;
+    }
+
+    psMinimizeLMChi2(min,
+                     myParams,
+                     NULL,
+                     myCovar,
+                     myCoords,
+                     y,
+                     (psMinimizeLMChi2Func) myFunc);
+
+    printf("\nThe chi-squared is %f\n", min->value);
+    for (i=0;i<NUM_PARAMS;i++) {
+        printf("Parameter %d at the minimum is %f (expected: %f)\n", i,
+               myParams->data.F32[i], expectedParm[i]);
+    }
+
+    psFree(myCoords);
+    psFree(myParams);
+    psFree(myParamMask);
+    psFree(min);
+    psFree(x);
+    psFree(y);
+    psFree(myCovar);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,NULL);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psStats00.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psStats00.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psStats00.c	(revision 2163)
@@ -0,0 +1,204 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_SAMPLE_MEAN is correctly computed
+    by the procedure psArrayStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#define N 10
+
+int main()
+{
+    psStats *myStats    = NULL;
+    psStats *myStats2    = NULL;
+    int testStatus      = true;
+    int globalTestStatus = true;
+    int i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    float mean          = 0.0;
+    float realMeanNoMask   = 0.0;
+    float realMeanWithMask = 0.0;
+    int count           = 0;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    mean = 0.0;
+    realMeanWithMask = 0.0;
+    // Set the appropriate values for the vector data.
+    for (i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+    }
+
+    // Set the mask vector and calculate the expected maximum.
+    for (i=0;i<N;i++) {
+        realMeanNoMask+= myVector->data.F32[i];
+
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+            realMeanWithMask+= myVector->data.F32[i];
+            count++;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+
+    realMeanNoMask /= (float) N;
+    realMeanWithMask /= (float) count;
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_MEAN: no vector mask");
+
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+    mean = myStats->sampleMean;
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The expected mean was %f; the calculated mean was %f\n", realMeanNoMask, mean);
+    if (mean == realMeanNoMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_MEAN: no vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask=1.                             */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_MEAN: with vector mask=1");
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+    mean = myStats->sampleMean;
+    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
+    printf("The expected mean was %f; the calculated mean was %f\n", realMeanWithMask, mean);
+    if (mean == realMeanWithMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_MEAN: with vector mask=1",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask=2.                             */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_MEAN: with vector mask=2");
+
+    // Set the mask vector and calculate the expected maximum.
+    // Set the mask vector.
+    for (i=0;i<N;i++) {
+        if (maskVector->data.U8[i] == 1) {
+            maskVector->data.U8[i] = 2;
+        }
+    }
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 2);
+    mean = myStats->sampleMean;
+    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
+    printf("The expected mean was %f; the calculated mean was %f\n", realMeanWithMask, mean);
+    if (mean == realMeanWithMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_MEAN: with vector mask=2",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask=3.                             */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_MEAN: with vector mask=3");
+
+    // Set the mask vector and calculate the expected maximum.
+    // Set the mask vector.
+    for (i=0;i<N;i++) {
+        if (maskVector->data.U8[i] == 2) {
+            maskVector->data.U8[i] = 3;
+        }
+    }
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 3);
+    mean = myStats->sampleMean;
+    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
+    printf("The expected mean was %f; the calculated mean was %f\n", realMeanWithMask, mean);
+    if (mean == realMeanWithMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_MEAN: with vector mask=3",
+                testStatus);
+    /*************************************************************************/
+    /*  Call psVectorStats() with NULL inputs.                               */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_MEAN: NULL inputs");
+
+    myStats = psVectorStats(myStats, NULL, NULL, 0);
+    myStats2 = psVectorStats(NULL, myVector, NULL, 0);
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_MEAN: NULL inputs",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                           */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "psStats(): deallocating memory");
+
+    psFree(myStats);
+    psFree(myVector);
+    psFree(maskVector);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psStats01.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psStats01.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psStats01.c	(revision 2163)
@@ -0,0 +1,125 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_MAX is correctly computed
+    by the procedure psVectorStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#define N 10
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int globalTestStatus = true;
+    int i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    float max           = 0.0;
+    float realMaxNoMask   = 0.0;
+    float realMaxWithMask = 0.0;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_MAX);
+    myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    // Set the appropriate values for the vector data.
+    for (i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+    }
+
+    // Set the mask vector and calculate the expected maximum.
+    for (i=0;i<N;i++) {
+        if (myVector->data.F32[i] > realMaxNoMask) {
+            realMaxNoMask = myVector->data.F32[i];
+        }
+
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+
+            if (myVector->data.F32[i] > realMaxWithMask) {
+                realMaxWithMask = myVector->data.F32[i];
+            }
+        } else {
+            maskVector->data.U8[i] = 1;
+            printf("Masking element %d\n", i);
+        }
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_MAX: no vector mask");
+
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+    max = myStats->max;
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The expected max was %f; the calculated max was %f\n", realMaxNoMask, max);
+    if (max == realMaxNoMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_MAX: no vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                       */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_MAX: with vector mask");
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+    max = myStats->max;
+    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
+    printf("The expected max was %f; the calculated max was %f\n", realMaxWithMask, max);
+    if (max == realMaxWithMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_MAX: with vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "psStats(): deallocating memory");
+
+    psFree(myStats);
+    psFree(myVector);
+    psFree(maskVector);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psStats02.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psStats02.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psStats02.c	(revision 2163)
@@ -0,0 +1,125 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_MIN is correctly computed
+    by the procedure psVectorStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#define N 10
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int globalTestStatus = true;
+    int i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    float min           = 1e99;
+    float realMinNoMask   = 1e99;
+    float realMinWithMask = 1e99;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_MIN);
+    myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    // Set the appropriate values for the vector data.
+    for (i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+    }
+
+    // Set the mask vector and calculate the expected minimum.
+    for (i=0;i<N;i++) {
+        if (myVector->data.F32[i] < realMinNoMask) {
+            realMinNoMask = myVector->data.F32[i];
+        }
+
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 1;
+        } else {
+            maskVector->data.U8[i] = 0;
+            if (myVector->data.F32[i] < realMinWithMask) {
+                realMinWithMask = myVector->data.F32[i];
+            }
+        }
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_MIN: no vector mask");
+
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+    min = myStats->min;
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The expected min was %f; the calculated min was %f\n",
+           realMinNoMask, min);
+    if (min == realMinNoMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_MIN: no vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                       */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_MIN: with vector mask");
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+    min = myStats->min;
+    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
+    printf("The expected min was %f; the calculated min was %f\n",
+           realMinWithMask, min);
+    if (min == realMinWithMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_MIN: with vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "psStats(): deallocating memory");
+
+    psFree(myStats);
+    psFree(myVector);
+    psFree(maskVector);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psStats03.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psStats03.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psStats03.c	(revision 2163)
@@ -0,0 +1,120 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_SAMPLE_MEDIAN is correctly computed
+    by the procedure psVectorStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#define N1 1029   // This should be an odd number.
+#define N ((4 * N1) + 1)
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int globalTestStatus = true;
+    int i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    float median        = 1e99;
+    float realMedianWithMask = (float) (N-3)/4;
+    float realMedianNoMask = (float) (N-1)/2;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN);
+    myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    // Set the appropriate values for the vector data.
+    for (i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+    }
+
+    // Set the mask vector and calculate the expected median.
+    for (i=0;i<N;i++) {
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_MEDIAN: no vector mask");
+
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+    median = myStats->sampleMedian;
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The expected median was %f.  The calculated median was %f.\n",
+           realMedianNoMask, median);
+    if (median == realMedianNoMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+
+    printFooter(stdout,
+                "psStats functions",
+                "PS_STAT_SAMPLE_MEDIAN: no vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                       */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_MEDIAN: with vector mask");
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+    median = myStats->sampleMedian;
+    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
+    printf("The expected median was %f.  The calculated median was %f.\n",
+           realMedianWithMask, median);
+    if (median == realMedianWithMask) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+
+    printFooter(stdout,
+                "psStats functions",
+                "PS_STAT_SAMPLE_MEDIAN: with vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "psStats(): deallocating memory");
+
+    psFree(myStats);
+    psFree(myVector);
+    psFree(maskVector);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psStats functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psStats04.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psStats04.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psStats04.c	(revision 2163)
@@ -0,0 +1,82 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_NVALUES is correctly computed
+    by the procedure psVectorStats().
+ 
+    Note: The NVALUES stat was removed from the IfA requirements spec.  So,
+    this test is no longer in use.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#define N1 1029
+#define N ((4 * N1) + 1)
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_NVALUES);
+    myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    // Set the appropriate values for the vector data.
+    for (i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+    }
+
+    // Set the mask vector and calculate the expected maximum.
+    for (i=0;i<N;i++) {
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_NVALUES");
+
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The expected nvalues was %d.  The calculated nvalues was %d.\n",
+           N, myStats->nValues);
+    if (myStats->nValues == N) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                       */
+    /*************************************************************************/
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
+    printf("The expected nvalues was %d.  The calculated nvalues was %d.\n",
+           N/2, myStats->nValues);
+    if (myStats->nValues == N/2) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+    }
+
+    printFooter(stdout,
+                "psHash functions",
+                "psHashAlloc()",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psStats05.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psStats05.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psStats05.c	(revision 2163)
@@ -0,0 +1,75 @@
+/*****************************************************************************
+    This routine must ensure that the psStats structure is correctly
+    allocated and deallocated by the procedure psArrayStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#define MISC_FLOAT_NUMBER 345.0
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "Allocate the psStats structure.");
+
+    myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    myStats->sampleMean = MISC_FLOAT_NUMBER;
+    myStats->sampleMedian = MISC_FLOAT_NUMBER;
+    myStats->sampleStdev = MISC_FLOAT_NUMBER;
+    myStats->sampleUQ = MISC_FLOAT_NUMBER;
+    myStats->sampleLQ = MISC_FLOAT_NUMBER;
+    myStats->robustMean = MISC_FLOAT_NUMBER;
+    myStats->robustMedian = MISC_FLOAT_NUMBER;
+    myStats->robustMode = MISC_FLOAT_NUMBER;
+    myStats->robustStdev = MISC_FLOAT_NUMBER;
+    myStats->robustUQ = MISC_FLOAT_NUMBER;
+    myStats->robustLQ = MISC_FLOAT_NUMBER;
+    myStats->robustN50 = MISC_FLOAT_NUMBER;
+    myStats->robustNfit = MISC_FLOAT_NUMBER;
+    myStats->clippedMean = MISC_FLOAT_NUMBER;
+    myStats->clippedStdev = MISC_FLOAT_NUMBER;
+    myStats->clipSigma = MISC_FLOAT_NUMBER;
+    myStats->clipIter = MISC_FLOAT_NUMBER;
+    myStats->min = MISC_FLOAT_NUMBER;
+    myStats->max = MISC_FLOAT_NUMBER;
+    myStats->binsize = MISC_FLOAT_NUMBER;
+    myStats->options = 0x0;
+
+    psMemCheckCorruption(1);
+
+    printFooter(stdout,
+                "psStats functions",
+                "Allocate the psStats structure.",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "Deallocate the psStats structure.");
+    psFree(myStats);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+    psMemCheckCorruption(1);
+
+    printFooter(stdout,
+                "psStats functions",
+                "Deallocate the psStats structure.",
+                testStatus);
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psStats06.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psStats06.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psStats06.c	(revision 2163)
@@ -0,0 +1,128 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_SAMPLE_STDEV is correctly computed
+    by the procedure psArrayStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psTest.h"
+#include "float.h"
+#include <math.h>
+
+#define N 15
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int globalTestStatus = true;
+    int i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    float stdev         = 0.0;
+    // NOTE: These values were calculated by running the function on the data.
+    // A: They must be changed if we adjust the number of data points.
+    // B: We don't really know that they are correct.
+    float realStdevNoMask   = 4.472136;
+    float realStdevWithMask = 2.160247;
+    int count           = 0;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_SAMPLE_STDEV);
+    myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    stdev = 0.0;
+    // Set the appropriate values for the vector data.
+    for (i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+    }
+
+    // Set the mask vector and calculate the expected maximum.
+    for (i=0;i<N;i++) {
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+            count++;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_STDEV: no vector mask");
+
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+    stdev = myStats->sampleStdev;
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The expected stdev was %f; the calculated stdev was %f\n",
+           realStdevNoMask, stdev);
+    if (fabs(stdev - realStdevNoMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_STDEV: no vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                       */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_STDEV: with vector mask");
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+    stdev = myStats->sampleStdev;
+    printf("Called psVectorStats() on a vector with last N/2 elements masked.\n");
+    printf("The expected stdev was %f; the calculated stdev was %f\n",
+           realStdevWithMask, stdev);
+    if (fabs(stdev - realStdevWithMask) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_STDEV: with vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "psStats(): deallocating memory");
+
+    psFree(myStats);
+    psFree(myVector);
+    psFree(maskVector);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psStats07.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psStats07.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psStats07.c	(revision 2163)
@@ -0,0 +1,423 @@
+/*****************************************************************************
+   This routine must ensure that PS_STAT_ROBUST_QUARTILE is correctly computed
+   by the procedure psArrayStats().
+*****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psTest.h"
+#include "float.h"
+#include <math.h>
+
+#define N 200
+#define MEAN 32.0
+#define STDEV 2.0
+#define ERROR_TOLERANCE 0.10
+
+int main()
+{
+    psStats * myStats = NULL;
+    int testStatus = true;
+    int globalTestStatus = true;
+    int i = 0;
+    psVector *myVector = NULL;
+    psVector *maskVector = NULL;
+    // NOTE: These values were calculated by running the function on the data.
+    // A: They must be changed if we adjust the number of data points.
+    // B: We don't really know that they are correct.
+    int count = 0;
+    int currentId = psMemGetId();
+    int memLeaks = 0;
+    float realMeanNoMask = MEAN;
+    float realMedianNoMask = MEAN;
+    float realModeNoMask = MEAN;
+    float realStdevNoMask = STDEV * 0.33;
+    float realLQNoMask = MEAN - ( 0.6 * STDEV );
+    float realUQNoMask = MEAN + ( 0.6 * STDEV );
+    int realN50NoMask = N / 4;
+    int realNfitNoMask = N / 4;
+    float realMeanWithMask = MEAN;
+    float realMedianWithMask = MEAN;
+    float realModeWithMask = MEAN;
+    float realStdevWithMask = STDEV;
+    float realLQWithMask = MEAN;
+    float realUQWithMask = MEAN;
+    int realN50WithMask = N / 4;
+    int realNfitWithMask = N / 4;
+
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                              */
+    /*************************************************************************/
+    myStats = psStatsAlloc( PS_STAT_ROBUST_MEAN |
+                            PS_STAT_ROBUST_MEDIAN |
+                            PS_STAT_ROBUST_MODE |
+                            PS_STAT_ROBUST_STDEV |
+                            PS_STAT_ROBUST_QUARTILE );
+
+    maskVector = psVectorAlloc( N, PS_TYPE_U8 );
+    maskVector->n = N;
+    myVector = psGaussianDev( MEAN, STDEV, N );
+    // Set the mask vector and calculate the expected maximum.
+    for ( i = 0;i < N;i++ ) {
+        if ( i < ( N / 2 ) ) {
+            maskVector->data.U8[ i ] = 0;
+            count++;
+        } else {
+            maskVector->data.U8[ i ] = 1;
+        }
+    }
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                            */
+    /*************************************************************************/
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "PS_STAT_ROBUST_STATS: robust mean: no vector mask" );
+
+    myStats = psVectorStats( myStats, myVector, NULL, 0 );
+
+    printf( "The expected Mean was %.2f; the calculated Mean was %.2f\n",
+            realMeanNoMask, myStats->robustMean );
+
+    if ( fabs( myStats->robustMean - realMeanNoMask ) < ( ERROR_TOLERANCE * realMeanNoMask ) ) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter( stdout,
+                 "psVector functions",
+                 "PS_STAT_ROBUST_STATS: robust mean: no vector mask",
+                 testStatus );
+
+
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "PS_STAT_ROBUST_STATS: robust Median: no vector mask" );
+
+    printf( "The expected Median was %.2f; the calculated Median was %.2f\n",
+            realMedianNoMask, myStats->robustMedian );
+    if ( fabs( myStats->robustMedian - realMedianNoMask ) < ( ERROR_TOLERANCE * realMedianNoMask ) ) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter( stdout,
+                 "psVector functions",
+                 "PS_STAT_ROBUST_STATS: robust Median: no vector mask",
+                 testStatus );
+
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "PS_STAT_ROBUST_STATS: robust Mode: no vector mask" );
+
+
+    printf( "The expected Mode was %.2f; the calculated Mode was %.2f\n",
+            realModeNoMask, myStats->robustMode );
+    if ( fabs( myStats->robustMode - realModeNoMask ) < ( ERROR_TOLERANCE * realModeNoMask ) ) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter( stdout,
+                 "psVector functions",
+                 "PS_STAT_ROBUST_STATS: robust Mode: no vector mask",
+                 testStatus );
+
+
+
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "PS_STAT_ROBUST_STATS: robust Stdev: no vector mask" );
+
+    printf( "The expected Stdev was %.2f; the calculated Stdev was %.2f\n",
+            realStdevNoMask, myStats->robustStdev );
+    if ( fabs( myStats->robustStdev - realStdevNoMask ) < ( ERROR_TOLERANCE * realStdevNoMask ) ) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter( stdout,
+                 "psVector functions",
+                 "PS_STAT_ROBUST_STATS: robust Stdev: no vector mask",
+                 testStatus );
+
+
+
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "PS_STAT_ROBUST_STATS: lower quartile: no vector mask" );
+
+    printf( "The expected LQ was %.2f; the calculated LQ was %.2f\n",
+            realLQNoMask, myStats->robustLQ );
+
+    if ( fabs( myStats->robustLQ - realLQNoMask ) < ( ERROR_TOLERANCE * realLQNoMask ) ) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter( stdout,
+                 "psVector functions",
+                 "PS_STAT_ROBUST_STATS: lower quartile: no vector mask",
+                 testStatus );
+
+
+
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "PS_STAT_ROBUST_STATS: upper quartile: no vector mask" );
+
+    printf( "The expected UQ was %.2f; the calculated UQ was %.2f\n",
+            realUQNoMask, myStats->robustUQ );
+    if ( fabs( myStats->robustUQ - realUQNoMask ) < ( ERROR_TOLERANCE * realUQNoMask ) ) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter( stdout,
+                 "psVector functions",
+                 "PS_STAT_ROBUST_STATS: lower quartile: no vector mask",
+                 testStatus );
+
+
+
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "PS_STAT_ROBUST_STATS: robust N50: no vector mask" );
+
+    // XXX:
+    realN50NoMask = myStats->robustN50;
+
+    printf( "The expected N50 was %d; the calculated N50 was %d\n",
+            realN50NoMask, myStats->robustN50 );
+    /* XXX: fix
+        if ( fabs( myStats->robustN50 - realN50NoMask ) < ( ERROR_TOLERANCE * realN50NoMask ) ) {
+            testStatus = true;
+        } else {
+            testStatus = false;
+            globalTestStatus = false;
+        }
+    */
+    printFooter( stdout,
+                 "psVector functions",
+                 "PS_STAT_ROBUST_STATS: robust N50: no vector mask",
+                 testStatus );
+
+
+
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "PS_STAT_ROBUST_STATS: robust Nfit: no vector mask" );
+
+    // XXX:
+    realNfitNoMask = myStats->robustNfit;
+
+    printf( "The expected Nfit was %d; the calculated Nfit was %d\n",
+            realNfitNoMask, myStats->robustNfit );
+    /* XXX: fix
+        if ( fabs( myStats->robustNfit - realNfitNoMask ) < ( ERROR_TOLERANCE * realNfitNoMask ) ) {
+            testStatus = true;
+        } else {
+            testStatus = false;
+            globalTestStatus = false;
+        }
+    */
+    printFooter( stdout,
+                 "psVector functions",
+                 "PS_STAT_ROBUST_STATS: robust Nfit: no vector mask",
+                 testStatus );
+
+
+    return ( 0 );
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                               */
+    /*************************************************************************/
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "PS_STAT_ROBUST_STATS: robust mean: with vector mask" );
+
+    printf( "Calling psVectorStats() on a vector with elements masked.\n" );
+    myStats = psVectorStats( myStats, myVector, maskVector, 1 );
+    printf( "Called psVectorStats() on a vector with elements masked.\n" );
+    printf( "The expected Mean was %.2f; the calculated Mean was %.2f\n",
+            realMeanWithMask, myStats->robustMean );
+    if ( fabs( myStats->robustMean - realMeanWithMask ) < ( ERROR_TOLERANCE * realMeanWithMask ) ) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter( stdout,
+                 "psVector functions",
+                 "PS_STAT_ROBUST_STATS: robust mean: with vector mask",
+                 testStatus );
+
+
+
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "PS_STAT_ROBUST_STATS: robust Median: with vector mask" );
+
+    printf( "The expected Median was %.2f; the calculated Median was %.2f\n",
+            realMedianWithMask, myStats->robustMedian );
+    if ( fabs( myStats->robustMedian - realMedianWithMask ) < ( ERROR_TOLERANCE * realMedianWithMask ) ) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter( stdout,
+                 "psVector functions",
+                 "PS_STAT_ROBUST_STATS: robust Median: with vector mask",
+                 testStatus );
+
+
+
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "PS_STAT_ROBUST_STATS: robust Mode: with vector mask" );
+
+    printf( "The expected Mode was %.2f; the calculated Mode was %.2f\n",
+            realModeWithMask, myStats->robustMode );
+    if ( fabs( myStats->robustMode - realModeWithMask ) < ( ERROR_TOLERANCE * realModeWithMask ) ) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter( stdout,
+                 "psVector functions",
+                 "PS_STAT_ROBUST_STATS: robust Mode: with vector mask",
+                 testStatus );
+
+
+
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "PS_STAT_ROBUST_STATS: robust Stdev: with vector mask" );
+
+    printf( "The expected Stdev was %.2f; the calculated Stdev was %.2f\n",
+            realStdevWithMask, myStats->robustStdev );
+    if ( fabs( myStats->robustStdev - realStdevWithMask ) < ( ERROR_TOLERANCE * realStdevWithMask ) ) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter( stdout,
+                 "psVector functions",
+                 "PS_STAT_ROBUST_STATS: robust Stdev: with vector mask",
+                 testStatus );
+
+
+
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "PS_STAT_ROBUST_STATS: lower quartile: with vector mask" );
+
+    printf( "The expected LQ was %.2f; the calculated LQ was %.2f\n",
+            realLQWithMask, myStats->robustLQ );
+    if ( fabs( myStats->robustLQ - realLQWithMask ) < ( ERROR_TOLERANCE * realLQWithMask ) ) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter( stdout,
+                 "psVector functions",
+                 "PS_STAT_ROBUST_STATS: lower quartile: with vector mask",
+                 testStatus );
+
+
+
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "PS_STAT_ROBUST_STATS: upper quartile: with vector mask" );
+
+    printf( "The expected UQ was %.2f; the calculated UQ was %.2f\n",
+            realUQWithMask, myStats->robustUQ );
+    if ( fabs( myStats->robustUQ - realUQWithMask ) < ( ERROR_TOLERANCE * realUQWithMask ) ) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter( stdout,
+                 "psVector functions",
+                 "PS_STAT_ROBUST_STATS: lower quartile: with vector mask",
+                 testStatus );
+
+
+
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "PS_STAT_ROBUST_STATS: robust N50: with vector mask" );
+
+    printf( "The expected N50 was %d; the calculated N50 was %d\n",
+            realN50WithMask, myStats->robustN50 );
+    /* XXX: fix
+        if ( fabs( myStats->robustN50 - realN50WithMask ) < ( ERROR_TOLERANCE * realN50WithMask ) ) {
+            testStatus = true;
+        } else {
+            testStatus = false;
+            globalTestStatus = false;
+        }
+    */
+    printFooter( stdout,
+                 "psVector functions",
+                 "PS_STAT_ROBUST_STATS: robust N50: with vector mask",
+                 testStatus );
+
+
+
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "PS_STAT_ROBUST_STATS: robust Nfit: with vector mask" );
+
+    printf( "The expected Nfit was %d; the calculated Nfit was %d\n",
+            realNfitWithMask, myStats->robustNfit );
+    /* XXX: fix
+        if ( fabs( myStats->robustNfit - realNfitWithMask ) < ( ERROR_TOLERANCE * realNfitWithMask ) ) {
+            testStatus = true;
+        } else {
+            testStatus = false;
+            globalTestStatus = false;
+        }
+    */
+    printFooter( stdout,
+                 "psVector functions",
+                 "PS_STAT_ROBUST_STATS: robust Nfit: with vector mask",
+                 testStatus );
+
+
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                           */
+    /*************************************************************************/
+    printPositiveTestHeader( stdout,
+                             "psStats functions",
+                             "psStats(): deallocating memory" );
+
+    psFree( myStats );
+    psFree( myVector );
+    psFree( maskVector );
+
+    psMemCheckCorruption( 1 );
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if ( 0 != memLeaks ) {
+        psAbort( __func__, "Memory Leaks! (%d leaks)", memLeaks );
+    }
+
+    printFooter( stdout,
+                 "psVector functions",
+                 "psStats(): deallocating memory",
+                 testStatus );
+
+    return ( !globalTestStatus );
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psStats08.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psStats08.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psStats08.c	(revision 2163)
@@ -0,0 +1,172 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_SAMPLE_QUARTILE is correctly computed
+    by the procedure psArrayStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psTest.h"
+#include "float.h"
+#include <math.h>
+
+#define N1 25  //
+#define N (8 * N1) // Don't change this (N must be a multiple of 8)
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int globalTestStatus = true;
+    int i               = 0;
+    psVector *myVector  = NULL;
+    psVector *maskVector= NULL;
+    // NOTE: These values were calculated by running the function on the data.
+    // A: They must be changed if we adjust the number of data points.
+    // B: We don't really know that they are correct.
+    float realLQNoMask   = N/4.0;
+    float realUQNoMask   = 3.0 * (N/4.0);
+    float realLQWithMask   = N/8.0;
+    float realUQWithMask   = 3.0 * (N/8.0);
+    int count           = 0;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_SAMPLE_QUARTILE);
+    myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    // Set the appropriate values for the vector data.
+    for (i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+    }
+
+    // Set the mask vector and calculate the expected maximum.
+    for (i=0;i<N;i++) {
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+            count++;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_LQ: no vector mask");
+
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The expected sampleLQ was %f; the calculated sampleLQ was %f\n",
+           realLQNoMask, myStats->sampleLQ);
+    if (fabs(realLQNoMask - myStats->sampleLQ) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_LQ: no vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_UQ: no vector mask");
+
+    myStats = psVectorStats(myStats, myVector, NULL, 0);
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The expected sampleUQ was %f; the calculated sampleUQ was %f\n",
+           realUQNoMask, myStats->sampleUQ);
+    if (fabs(realUQNoMask - myStats->sampleUQ) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_UQ: no vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                       */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_LQ: with vector mask");
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+
+    printf("Called psVectorStats() on a vector with elements masked.\n");
+    printf("The expected sampleLQ was %f; the calculated sampleLQ was %f\n",
+           realLQWithMask, myStats->sampleLQ);
+    if (fabs(realLQWithMask - myStats->sampleLQ) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_LQ: with vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_SAMPLE_UQ: with vector mask");
+
+    myStats = psVectorStats(myStats, myVector, maskVector, 1);
+
+    printf("Called psVectorStats() on a vector with elements masked.\n");
+    printf("The expected sampleUQ was %f; the calculated sampleUQ was %f\n",
+           realUQWithMask, myStats->sampleUQ);
+    if (fabs(realUQWithMask - myStats->sampleUQ) <= 2.0 * FLT_EPSILON) {
+        testStatus = true;
+    } else {
+        testStatus = false;
+        globalTestStatus = false;
+    }
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_SAMPLE_UQ: with vector mask",
+                testStatus);
+
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "psStats(): deallocating memory");
+
+    psFree(myStats);
+    psFree(myVector);
+    psFree(maskVector);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psStats09.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psStats09.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psStats09.c	(revision 2163)
@@ -0,0 +1,146 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_CLIPPED_MEAN and
+    PS_STAT_CLIPPED_STDEV is calculate correctly by the procedure
+    psVectorStats().
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psTest.h"
+#include "psImageStats.h"
+#include "float.h"
+#include <math.h>
+
+#define N 500
+#define MY_MEAN  30.0
+#define MY_RANGE 2.0
+
+int main()
+{
+    psStats *myStats    = NULL;
+    int testStatus      = true;
+    int globalTestStatus = true;
+    int i               = 0;
+    psVector *maskVector= NULL;
+    psVector *myGaussData  = NULL;
+    // NOTE: These values were calculated by running the function on the data.
+    // A: They must be changed if we adjust the number of data points.
+    // B: We don't really know that they are correct.
+    //    float realclippedMeanNoMask  = 0.0;
+    //    float realclippedStdevNoMask = 0.0;
+    //    float realclippedMeanWithMask  = 0.0;
+    //    float realclippedStdevWithMask = 0.0;
+    int count           = 0;
+    int currentId       = psMemGetId();
+    int memLeaks        = 0;
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    myStats = psStatsAlloc(PS_STAT_CLIPPED_MEAN |
+                           PS_STAT_CLIPPED_STDEV);
+
+    myGaussData = psVectorAlloc(N, PS_TYPE_F32);
+    myGaussData->n = myGaussData->nalloc;
+    for (i=0;i<N;i++) {
+        myGaussData->data.F32[i] = MY_MEAN - (MY_RANGE/1.9) +
+                                   (MY_RANGE) * ((float) i) / ((float) N);
+    }
+
+    maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+
+    // Set the mask vector and calculate the expected maximum.
+    for (i=0;i<N;i++) {
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+            count++;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_CLIPPED_MEAN: no vector mask");
+
+    myStats = psVectorStats(myStats, myGaussData, NULL, 0);
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The calculated clippedMean was %f\n", myStats->clippedMean);
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_CLIPPED_MEAN/STDEV: no vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_CLIPPED_STDEV: no vector mask");
+
+    printf("Called psVectorStats() on a vector with no elements masked.\n");
+    printf("The calculated clippedStdev was %f\n", myStats->clippedStdev);
+
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_CLIPPED_MEAN/STDEV: no vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                       */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_CLIPPED_MEAN: vector mask");
+
+    myStats = psVectorStats(myStats, myGaussData, maskVector, 1);
+
+    printf("Called psVectorStats() on a vector with elements masked.\n");
+    printf("The calculated clippedMean was %f\n", myStats->clippedMean);
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_CLIPPED_MEAN/STDEV: vector mask",
+                testStatus);
+
+
+
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "PS_STAT_CLIPPED_STDEV: vector mask");
+
+    printf("Called psVectorStats() on a vector with elements masked.\n");
+    printf("The calculated clippedStdev was %f\n", myStats->clippedStdev);
+    printFooter(stdout,
+                "psVector functions",
+                "PS_STAT_CLIPPED_MEAN/STDEV: vector mask",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psStats functions",
+                            "psStats(): deallocating memory");
+
+    psFree(myStats);
+    psFree(myGaussData);
+    psFree(maskVector);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter(stdout,
+                "psVector functions",
+                "psStats(): deallocating memory",
+                testStatus);
+
+    return (!globalTestStatus);
+}
Index: /branches/rel3/psLib/test/dataManip/tst_psVectorFFT.c
===================================================================
--- /branches/rel3/psLib/test/dataManip/tst_psVectorFFT.c	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/tst_psVectorFFT.c	(revision 2163)
@@ -0,0 +1,389 @@
+/** @file  tst_psVectorFFT.c
+*
+*  @brief Contains the tests for psFFT.[ch]
+*
+*
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-08-06 22:34:06 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include <math.h>
+#include <float.h>
+
+#include "psTest.h"
+#include "pslib.h"
+
+#define GENIMAGE(img,c,r,TYP, valueFcn) \
+img = psImageAlloc(c,r,PS_TYPE_##TYP); \
+for (unsigned int row=0;row<r;row++) { \
+    ps##TYP* imgRow = img->data.TYP[row]; \
+    for (unsigned int col=0;col<c;col++) { \
+        imgRow[col] = (ps##TYP)(valueFcn); \
+    } \
+}
+
+static int testVectorFFT( void );
+static int testVectorRealImaginary( void );
+static int testVectorComplex( void );
+static int testVectorConjugate( void );
+static int testVectorPowerSpectrum( void );
+
+testDescription tests[] = {
+                              {
+                                  testVectorFFT, 600, "psVectorFFT", 0, false
+                              },
+                              {
+                                  testVectorRealImaginary, 601, "psVectorRealImaginary", 0, false
+                              },
+                              {
+                                  testVectorComplex, 602, "psVectorComplex", 0, false
+                              },
+                              {
+                                  testVectorConjugate, 603, "psVectorConjugate", 0, false
+                              },
+                              {
+                                  testVectorPowerSpectrum, 604, "psVectorPowerSpectrum", 0, false
+                              },
+                              {
+                                  NULL
+                              }
+                          };
+
+int main( int argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psFFT", tests, argc, argv ) );
+}
+
+int testVectorFFT( void )
+{
+    psVector * vec = NULL;
+    psVector* vec2 = NULL;
+    psVector* vec3 = NULL;
+
+    /*
+    1. assign a vector to a sinisoid
+    2. perform a forward transform
+    3. verify that the only significant component cooresponds to the freqency of the input in step 1.
+    4. perform a reverse transform
+    5. compare to original (should be equal to within a reasonable error)
+    */
+
+    // 1. assign a vector to a sinisoid
+    vec = psVectorAlloc( 100, PS_TYPE_F32 );
+    vec->n = vec->nalloc;
+    for ( unsigned int n = 0; n < 100; n++ ) {
+        vec->data.F32[ n ] = sinf( ( psF32 ) n / 50.0f * M_PI );
+    }
+
+    // 2. perform a forward transform
+    vec2 = psVectorFFT( NULL, vec, PS_FFT_FORWARD );
+    if ( vec2->type.type != PS_TYPE_C32 ) {
+        psError( __func__, "FFT didn't produce complex values?" );
+        return 1;
+    }
+
+
+    // 3. verify that the only significant component cooresponds to the freqency of the input in step 1.
+    for ( unsigned int n = 0; n < 100; n++ ) {
+        if ( n == 1 || n == 99 ) {
+            if ( fabsf( cabsf( vec2->data.C32[ n ] ) - 50.0f ) > 0.1f ) {
+                psError( __func__, "FFT didn't work for vector (n=%d)", n );
+                return 2;
+            }
+        } else {
+            if ( fabsf( cabsf( vec2->data.C32[ n ] ) ) > 0.1f ) {
+                psError( __func__, "FFT didn't work for vector (n=%d)", n );
+                return 3;
+            }
+        }
+    }
+
+    // 4. perform a reverse transform
+    vec3 = psVectorFFT( NULL, vec2, PS_FFT_REVERSE );
+    if ( vec3->type.type != PS_TYPE_C32 ) {
+        psError( __func__, "FFT didn't produce complex values?" );
+        return 4;
+    }
+    for ( unsigned int n = 0; n < 100; n++ ) {
+        psF32 val = sinf( ( psF32 ) n / 50.0f * M_PI );
+        psF32 vecVal = crealf( vec3->data.C32[ n ] ) / 100;
+        if ( fabsf( vecVal - val ) > 0.1f ) {
+            psError( __func__, "Reverse FFT didn't give me the original vector back (n=%d) (%.2f vs %.2f)",
+                     n, vecVal, val );
+            return 5;
+        }
+    }
+
+    psFree( vec );
+    psFree( vec2 );
+    psFree( vec3 );
+
+    return 0;
+}
+
+int testVectorRealImaginary( void )
+{
+    psVector * vec = NULL;
+    psVector* vec2 = NULL;
+    psVector* vec3 = NULL;
+
+    /*
+    1. create a C32 complex vector with distinctly different real and imaginary parts.
+    2. call psVectorReal and psVectorImaginary
+    3. compare results to the real/imaginary components of input
+    */
+
+    // 1. create a C32 complex vector with distinctly different real and imaginary parts.
+    vec = psVectorAlloc( 100, PS_TYPE_C32 );
+    vec->n = vec->nalloc;
+    for ( unsigned int n = 0; n < 100; n++ ) {
+        vec->data.C32[ n ] = n + I * ( n * 2 );
+    }
+
+    // 2. call psVectorReal and psVectorImaginary
+    vec2 = psVectorReal( vec2, vec );
+    if ( vec2 == NULL ) {
+        psError( __func__, "psVectorReal returned a NULL?" );
+        return 1;
+    }
+    if ( vec2->type.type != PS_TYPE_F32 ) {
+        psError( __func__, "psVectorReal returned a wrong type (%d)?",
+                 vec2->type.type );
+        return 2;
+    }
+
+    vec3 = psVectorImaginary( vec3, vec );
+    if ( vec3 == NULL ) {
+        psError( __func__, "psVectorImaginary returned a NULL?" );
+        return 3;
+    }
+    if ( vec3->type.type != PS_TYPE_F32 ) {
+        psError( __func__, "psVectorImaginary returned a wrong type (%d)?",
+                 vec3->type.type );
+        return 4;
+    }
+
+    // 3. compare results to the real/imaginary components of input
+    for ( unsigned int n = 0; n < 100; n++ ) {
+        psF32 r = n;
+        psF32 i = ( n * 2 );
+        if ( fabsf( vec2->data.F32[ n ] - r ) > FLT_EPSILON ) {
+            psError( __func__, "psVectorReal didn't return the real portion at n=%d",
+                     n );
+            return 5;
+        }
+        if ( fabsf( vec3->data.F32[ n ] - i ) > FLT_EPSILON ) {
+            psError( __func__, "psVectorImaginary didn't return the real portion at n=%d",
+                     n );
+            return 6;
+        }
+    }
+
+    psFree( vec );
+    psFree( vec2 );
+    psFree( vec3 );
+
+    return 0;
+}
+
+int testVectorComplex( void )
+{
+    psVector * vec = NULL;
+    psVector* vec2 = NULL;
+    psVector* vec3 = NULL;
+
+    /*
+    1. create two unique psF32 vectors of the same size
+    2. call psVectorComplex
+    3. verify that the result is a psC32
+    4. call psVectorReal and psVectorImaginary on step 2 results
+    5. compare step 4 results to input.
+
+    6. create a psF32 and a psF64 vector of the same size
+    7. call psVectorComplex
+    8. verify that an appropriate error occurred.
+
+    9. create two psf32 vectors of different sizes
+    10. call psVectorComplex
+    11. verify thet an appropriate error occurred.
+    */
+
+    // 1. create two unique psF32 vectors of the same size
+    vec = psVectorAlloc( 100, PS_TYPE_F32 );
+    vec2 = psVectorAlloc( 100, PS_TYPE_F32 );
+    vec->n = vec->nalloc;
+    vec2->n = vec2->nalloc;
+    for ( unsigned int n = 0; n < 100; n++ ) {
+        vec->data.F32[ n ] = n;
+        vec2->data.F32[ n ] = ( n * 2 );
+    }
+
+    // 2. call psVectorComplex
+    vec3 = psVectorComplex( vec3, vec, vec2 );
+
+    // 3. verify that the result is a psC32
+    if ( vec3->type.type != PS_TYPE_C32 ) {
+        psError( __func__, "Vector Type from psVectorComplex is not complex? (%d)",
+                 vec3->type.type );
+        return 1;
+    }
+
+    // 4. call psVectorReal and psVectorImaginary on step 2 results (not needed, just use crealf/cimagf)
+    // 5. compare step 4 results to input.
+    for ( unsigned int n = 0; n < 100; n++ ) {
+        if ( fabsf( crealf( vec3->data.C32[ n ] ) - n ) > FLT_EPSILON ||
+                fabsf( cimagf( vec3->data.C32[ n ] ) - ( n * 2 ) ) > FLT_EPSILON ) {
+            psError( __func__, "psVectorComplex result is invalid (n=%d, %.2f+%.2fi)",
+                     n, crealf( vec3->data.C32[ n ] ), cimagf( vec3->data.C32[ n ] ) );
+            return 2;
+        };
+    }
+
+
+    // 6. create a psF32 and a psF64 vector of the same size
+    vec2 = psVectorRecycle( vec2, 100, PS_TYPE_F64 );
+
+    // 7. call psVectorComplex
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error (type mismatch)." );
+    vec3 = psVectorComplex( vec3, vec, vec2 );
+    // 8. verify that an appropriate error occurred. (this partially has to be done via inspection)
+    if ( vec3 != NULL ) {
+        psError( __func__, "psVectorComplex returned a vector though input types mismatched." );
+        return 3;
+    }
+
+    // 9. create two psf32 vectors of different sizes
+    vec2 = psVectorRecycle( vec2, 200, PS_TYPE_F32 );
+
+    // 10. call psVectorComplex
+    vec3 = psVectorComplex( vec3, vec, vec2 );
+
+    // 11. verify thet an appropriate error occurred. (actually, it isn't an error...)
+    if ( vec3->n != 100 ) {
+        psError( __func__, "psVectorComplex returned a larger vector than the input supported (%d).", vec3->n );
+        return 4;
+    }
+
+    psFree( vec );
+    psFree( vec2 );
+    psFree( vec3 );
+
+    return 0;
+}
+
+int testVectorConjugate( void )
+{
+    psVector * vec = NULL;
+    psVector* vec2 = NULL;
+
+    /*
+    1. create a psC32 with unique real and imaginary values.
+    2. call psVectorConjugate
+    3. verify result is psC32
+    4. verify each value is conjugate of input (a+bi -> a-bi)
+    */
+
+    // 1. create a psC32 with unique real and imaginary values.
+    vec = psVectorAlloc( 100, PS_TYPE_C32 );
+    vec->n = vec->nalloc;
+    for ( unsigned int n = 0; n < 100; n++ ) {
+        vec->data.C32[ n ] = n + I * ( n * 2 );
+    }
+
+    // 2. call psVectorConjugate
+    vec2 = psVectorConjugate( vec2, vec );
+
+    // 3. verify result is psC32
+    if ( vec2->type.type != PS_TYPE_C32 ) {
+        psError( __func__, "the psVectorConjugate didn't return a C32 vector" );
+        return 1;
+    }
+
+    // 4. verify each value is conjugate of input (a+bi -> a-bi)
+    for ( unsigned int n = 0; n < 100; n++ ) {
+        if ( fabsf( crealf( vec->data.C32[ n ] ) - crealf( vec2->data.C32[ n ] ) ) > FLT_EPSILON ||
+                fabsf( cimagf( vec->data.C32[ n ] ) + cimagf( vec2->data.C32[ n ] ) ) > FLT_EPSILON ) {
+            psError( __func__, "psVectorComplex result is invalid (n=%d, %.2f+%.2fi)",
+                     n, crealf( vec2->data.C32[ n ] ), cimagf( vec2->data.C32[ n ] ) );
+            return 2;
+        };
+    }
+
+    psFree( vec );
+    psFree( vec2 );
+
+    return 0;
+}
+
+int testVectorPowerSpectrum( void )
+{
+    psVector * vec = NULL;
+    psVector* vec2 = NULL;
+    psF32 val;
+
+    /*
+    1. create a psC32 vector with unique real and imaginary components
+    2. call psVectorPowerSpectrum
+    3. verify result is psF32
+    4. verify the values are the square of the absolute values of the original
+    */
+
+    // 1. create a psC32 vector with unique real and imaginary components
+    vec = psVectorAlloc( 100, PS_TYPE_C32 );
+    vec->n = vec->nalloc;
+    for ( unsigned int n = 0; n < 100; n++ ) {
+        vec->data.C32[ n ] = n + I * sinf( ( ( psF32 ) n ) / 50.f * M_PI );
+    }
+
+    // 2. call psVectorPowerSpectrum
+    vec2 = psVectorPowerSpectrum( vec2, vec );
+
+    // 3. verify result is psF32
+    if ( vec2->type.type != PS_TYPE_F32 ) {
+        psError( __func__, "the type was not PS_TYPE_F32." );
+        return 1;
+    }
+
+    // 4. verify the values are the square of the absolute values of the original
+    //   (ADD specifies something else)
+    //   P_0 = |C_0|^2/N^2
+    //   P_j = (|C_j|^2+|C_N-j|^2)/N^2
+    //   P_N/2 = |C_N/2|^2/N^2
+    //  where j = 1,2,...,(N/2-1)
+
+    val = cabsf( vec->data.C32[ 0 ] ) * cabsf( vec->data.C32[ 0 ] ) / 100 / 100;
+    if ( fabsf( vec2->data.F32[ 0 ] - val ) > FLT_EPSILON ) {
+        psError( __func__, "psVectorPowerSpectrum result is invalid (n=0, %.2f %.2f)",
+                 vec2->data.F32[ 0 ], val );
+        return 2;
+    };
+
+    for ( unsigned int n = 1; n < 50; n++ ) {
+        val = ( cabsf( vec->data.C32[ n ] ) * cabsf( vec->data.C32[ n ] ) +
+                cabsf( vec->data.C32[ 100 - n ] ) * cabsf( vec->data.C32[ 100 - n ] ) ) / 100 / 100;
+
+        if ( fabsf( val - vec2->data.F32[ n ] ) > FLT_EPSILON ) {
+            psError( __func__, "psVectorPowerSpectrum result is invalid (n=%d, %.2f %.2f)",
+                     n, vec2->data.F32[ n ], val );
+            return 2;
+        };
+    }
+
+    val = cabsf( vec->data.C32[ 50 ] ) * cabsf( vec->data.C32[ 50 ] ) / 100 / 100;
+    if ( fabsf( vec2->data.F32[ 50 ] - val ) > FLT_EPSILON ) {
+        psError( __func__, "psVectorPowerSpectrum result is invalid (n=50, %.2f %.2f)",
+                 vec2->data.F32[ 0 ], val );
+        return 2;
+    };
+
+    psFree( vec );
+    psFree( vec2 );
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psFunc01.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psFunc01.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psFunc01.stdout	(revision 2163)
@@ -0,0 +1,108 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc01.c                                             *
+*            TestPoint: psFunctions functions{psGaussian()}                        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+normal psGaussian(0.000000) is 0.000000
+normal psGaussian(2.000000) is 0.000000
+normal psGaussian(4.000000) is 0.000000
+normal psGaussian(6.000000) is 0.000000
+normal psGaussian(8.000000) is 0.000000
+normal psGaussian(10.000000) is 0.000000
+normal psGaussian(12.000000) is 0.000000
+normal psGaussian(14.000000) is 0.000000
+normal psGaussian(16.000000) is 0.000000
+normal psGaussian(18.000000) is 0.000000
+normal psGaussian(20.000000) is 0.000001
+normal psGaussian(22.000000) is 0.000067
+normal psGaussian(24.000000) is 0.002216
+normal psGaussian(26.000000) is 0.026995
+normal psGaussian(28.000000) is 0.120985
+normal psGaussian(30.000000) is 0.199471
+normal psGaussian(32.000000) is 0.120985
+normal psGaussian(34.000000) is 0.026995
+normal psGaussian(36.000000) is 0.002216
+normal psGaussian(38.000000) is 0.000067
+normal psGaussian(40.000000) is 0.000001
+normal psGaussian(42.000000) is 0.000000
+normal psGaussian(44.000000) is 0.000000
+normal psGaussian(46.000000) is 0.000000
+normal psGaussian(48.000000) is 0.000000
+normal psGaussian(50.000000) is 0.000000
+normal psGaussian(52.000000) is 0.000000
+normal psGaussian(54.000000) is 0.000000
+normal psGaussian(56.000000) is 0.000000
+normal psGaussian(58.000000) is 0.000000
+NON-normal psGaussian(0.000000) is 0.000000
+NON-normal psGaussian(2.000000) is 0.000000
+NON-normal psGaussian(4.000000) is 0.000000
+NON-normal psGaussian(6.000000) is 0.000000
+NON-normal psGaussian(8.000000) is 0.000000
+NON-normal psGaussian(10.000000) is 0.000000
+NON-normal psGaussian(12.000000) is 0.000000
+NON-normal psGaussian(14.000000) is 0.000000
+NON-normal psGaussian(16.000000) is 0.000000
+NON-normal psGaussian(18.000000) is 0.000000
+NON-normal psGaussian(20.000000) is 0.000004
+NON-normal psGaussian(22.000000) is 0.000335
+NON-normal psGaussian(24.000000) is 0.011109
+NON-normal psGaussian(26.000000) is 0.135335
+NON-normal psGaussian(28.000000) is 0.606531
+NON-normal psGaussian(30.000000) is 1.000000
+NON-normal psGaussian(32.000000) is 0.606531
+NON-normal psGaussian(34.000000) is 0.135335
+NON-normal psGaussian(36.000000) is 0.011109
+NON-normal psGaussian(38.000000) is 0.000335
+NON-normal psGaussian(40.000000) is 0.000004
+NON-normal psGaussian(42.000000) is 0.000000
+NON-normal psGaussian(44.000000) is 0.000000
+NON-normal psGaussian(46.000000) is 0.000000
+NON-normal psGaussian(48.000000) is 0.000000
+NON-normal psGaussian(50.000000) is 0.000000
+NON-normal psGaussian(52.000000) is 0.000000
+NON-normal psGaussian(54.000000) is 0.000000
+NON-normal psGaussian(56.000000) is 0.000000
+NON-normal psGaussian(58.000000) is 0.000000
+
+---> TESTPOINT PASSED (psFunctions functions{psGaussian()} | tst_psFunc01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psFunc01.c                                             *
+*            TestPoint: psFunctions functions{psGaussianDev()}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Gaussian Deviate [0] is 30.267838
+Gaussian Deviate [1] is 29.823797
+Gaussian Deviate [2] is 33.348816
+Gaussian Deviate [3] is 31.467281
+Gaussian Deviate [4] is 31.995049
+Gaussian Deviate [5] is 27.444996
+Gaussian Deviate [6] is 25.206570
+Gaussian Deviate [7] is 28.641439
+Gaussian Deviate [8] is 29.921818
+Gaussian Deviate [9] is 31.787111
+Gaussian Deviate [10] is 29.964705
+Gaussian Deviate [11] is 27.406887
+Gaussian Deviate [12] is 28.664040
+Gaussian Deviate [13] is 30.363417
+Gaussian Deviate [14] is 31.662102
+Gaussian Deviate [15] is 28.903503
+Gaussian Deviate [16] is 28.723936
+Gaussian Deviate [17] is 30.014177
+Gaussian Deviate [18] is 28.660292
+Gaussian Deviate [19] is 28.344475
+Gaussian Deviate [20] is 31.225000
+Gaussian Deviate [21] is 29.264824
+Gaussian Deviate [22] is 29.421013
+Gaussian Deviate [23] is 28.166250
+Gaussian Deviate [24] is 28.832390
+Gaussian Deviate [25] is 30.129230
+Gaussian Deviate [26] is 30.093487
+Gaussian Deviate [27] is 28.498547
+Gaussian Deviate [28] is 29.711535
+Gaussian Deviate [29] is 32.951122
+
+---> TESTPOINT PASSED (psFunctions functions{psGaussianDev()} | tst_psFunc01.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psHist00.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psHist00.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psHist00.stdout	(revision 2163)
@@ -0,0 +1,87 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist00.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000 - 30.000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure.} | tst_psHist00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist00.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000 - 25.000)
+Bin number 1 bounds: (25.000 - 30.000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure.} | tst_psHist00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist00.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000 - 21.000)
+Bin number 1 bounds: (21.000 - 22.000)
+Bin number 2 bounds: (22.000 - 23.000)
+Bin number 3 bounds: (23.000 - 24.000)
+Bin number 4 bounds: (24.000 - 25.000)
+Bin number 5 bounds: (25.000 - 26.000)
+Bin number 6 bounds: (26.000 - 27.000)
+Bin number 7 bounds: (27.000 - 28.000)
+Bin number 8 bounds: (28.000 - 29.000)
+Bin number 9 bounds: (29.000 - 30.000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure.} | tst_psHist00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist00.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000 - 20.500)
+Bin number 1 bounds: (20.500 - 21.000)
+Bin number 2 bounds: (21.000 - 21.500)
+Bin number 3 bounds: (21.500 - 22.000)
+Bin number 4 bounds: (22.000 - 22.500)
+Bin number 5 bounds: (22.500 - 23.000)
+Bin number 6 bounds: (23.000 - 23.500)
+Bin number 7 bounds: (23.500 - 24.000)
+Bin number 8 bounds: (24.000 - 24.500)
+Bin number 9 bounds: (24.500 - 25.000)
+Bin number 10 bounds: (25.000 - 25.500)
+Bin number 11 bounds: (25.500 - 26.000)
+Bin number 12 bounds: (26.000 - 26.500)
+Bin number 13 bounds: (26.500 - 27.000)
+Bin number 14 bounds: (27.000 - 27.500)
+Bin number 15 bounds: (27.500 - 28.000)
+Bin number 16 bounds: (28.000 - 28.500)
+Bin number 17 bounds: (28.500 - 29.000)
+Bin number 18 bounds: (29.000 - 29.500)
+Bin number 19 bounds: (29.500 - 30.000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure.} | tst_psHist00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist00.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure. (UPPER<LOWER)} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure. (UPPER<LOWER)} | tst_psHist00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist00.c                                             *
+*            TestPoint: psStats functions{Deallocate the psHistogram structure.}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{Deallocate the psHistogram structure.} | tst_psHist00.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psHist01.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psHist01.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psHist01.stdout	(revision 2163)
@@ -0,0 +1,78 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist01.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000 - 30.000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure.} | tst_psHist01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist01.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000 - 25.000)
+Bin number 1 bounds: (25.000 - 30.000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure.} | tst_psHist01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist01.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000 - 21.000)
+Bin number 1 bounds: (21.000 - 22.000)
+Bin number 2 bounds: (22.000 - 23.000)
+Bin number 3 bounds: (23.000 - 24.000)
+Bin number 4 bounds: (24.000 - 25.000)
+Bin number 5 bounds: (25.000 - 26.000)
+Bin number 6 bounds: (26.000 - 27.000)
+Bin number 7 bounds: (27.000 - 28.000)
+Bin number 8 bounds: (28.000 - 29.000)
+Bin number 9 bounds: (29.000 - 30.000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure.} | tst_psHist01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist01.c                                             *
+*            TestPoint: psStats functions{Allocate the psHistogram structure.}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000 - 20.500)
+Bin number 1 bounds: (20.500 - 21.000)
+Bin number 2 bounds: (21.000 - 21.500)
+Bin number 3 bounds: (21.500 - 22.000)
+Bin number 4 bounds: (22.000 - 22.500)
+Bin number 5 bounds: (22.500 - 23.000)
+Bin number 6 bounds: (23.000 - 23.500)
+Bin number 7 bounds: (23.500 - 24.000)
+Bin number 8 bounds: (24.000 - 24.500)
+Bin number 9 bounds: (24.500 - 25.000)
+Bin number 10 bounds: (25.000 - 25.500)
+Bin number 11 bounds: (25.500 - 26.000)
+Bin number 12 bounds: (26.000 - 26.500)
+Bin number 13 bounds: (26.500 - 27.000)
+Bin number 14 bounds: (27.000 - 27.500)
+Bin number 15 bounds: (27.500 - 28.000)
+Bin number 16 bounds: (28.000 - 28.500)
+Bin number 17 bounds: (28.500 - 29.000)
+Bin number 18 bounds: (29.000 - 29.500)
+Bin number 19 bounds: (29.500 - 30.000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psHistogram structure.} | tst_psHist01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist01.c                                             *
+*            TestPoint: psStats functions{Deallocate the psHistogram structure.}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{Deallocate the psHistogram structure.} | tst_psHist01.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psHist02.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psHist02.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psHist02.stdout	(revision 2163)
@@ -0,0 +1,156 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Allocate and Perform Histogram, no mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.00 - 30.00) data (10000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate and Perform Histogram, no mask} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Allocate and Perform Histogram with mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000 - 30.000) data (5000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate and Perform Histogram with mask} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Allocate and Perform Histogram, no mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.00 - 25.00) data (5000)
+Bin number 1 bounds: (25.00 - 30.00) data (5000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate and Perform Histogram, no mask} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Allocate and Perform Histogram with mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000 - 25.000) data (5000)
+Bin number 1 bounds: (25.000 - 30.000) data (0)
+
+---> TESTPOINT PASSED (psStats functions{Allocate and Perform Histogram with mask} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Allocate and Perform Histogram, no mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.00 - 21.00) data (1000)
+Bin number 1 bounds: (21.00 - 22.00) data (1000)
+Bin number 2 bounds: (22.00 - 23.00) data (1000)
+Bin number 3 bounds: (23.00 - 24.00) data (1000)
+Bin number 4 bounds: (24.00 - 25.00) data (1000)
+Bin number 5 bounds: (25.00 - 26.00) data (1000)
+Bin number 6 bounds: (26.00 - 27.00) data (1000)
+Bin number 7 bounds: (27.00 - 28.00) data (1000)
+Bin number 8 bounds: (28.00 - 29.00) data (1000)
+Bin number 9 bounds: (29.00 - 30.00) data (1000)
+
+---> TESTPOINT PASSED (psStats functions{Allocate and Perform Histogram, no mask} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Allocate and Perform Histogram with mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000 - 21.000) data (1000)
+Bin number 1 bounds: (21.000 - 22.000) data (1000)
+Bin number 2 bounds: (22.000 - 23.000) data (1000)
+Bin number 3 bounds: (23.000 - 24.000) data (1000)
+Bin number 4 bounds: (24.000 - 25.000) data (1000)
+Bin number 5 bounds: (25.000 - 26.000) data (0)
+Bin number 6 bounds: (26.000 - 27.000) data (0)
+Bin number 7 bounds: (27.000 - 28.000) data (0)
+Bin number 8 bounds: (28.000 - 29.000) data (0)
+Bin number 9 bounds: (29.000 - 30.000) data (0)
+
+---> TESTPOINT PASSED (psStats functions{Allocate and Perform Histogram with mask} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Allocate and Perform Histogram, no mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.00 - 20.50) data (500)
+Bin number 1 bounds: (20.50 - 21.00) data (500)
+Bin number 2 bounds: (21.00 - 21.50) data (500)
+Bin number 3 bounds: (21.50 - 22.00) data (500)
+Bin number 4 bounds: (22.00 - 22.50) data (500)
+Bin number 5 bounds: (22.50 - 23.00) data (500)
+Bin number 6 bounds: (23.00 - 23.50) data (500)
+Bin number 7 bounds: (23.50 - 24.00) data (500)
+Bin number 8 bounds: (24.00 - 24.50) data (500)
+Bin number 9 bounds: (24.50 - 25.00) data (500)
+Bin number 10 bounds: (25.00 - 25.50) data (500)
+Bin number 11 bounds: (25.50 - 26.00) data (500)
+Bin number 12 bounds: (26.00 - 26.50) data (500)
+Bin number 13 bounds: (26.50 - 27.00) data (500)
+Bin number 14 bounds: (27.00 - 27.50) data (500)
+Bin number 15 bounds: (27.50 - 28.00) data (500)
+Bin number 16 bounds: (28.00 - 28.50) data (500)
+Bin number 17 bounds: (28.50 - 29.00) data (500)
+Bin number 18 bounds: (29.00 - 29.50) data (500)
+Bin number 19 bounds: (29.50 - 30.00) data (500)
+
+---> TESTPOINT PASSED (psStats functions{Allocate and Perform Histogram, no mask} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Allocate and Perform Histogram with mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (20.000 - 20.500) data (500)
+Bin number 1 bounds: (20.500 - 21.000) data (500)
+Bin number 2 bounds: (21.000 - 21.500) data (500)
+Bin number 3 bounds: (21.500 - 22.000) data (500)
+Bin number 4 bounds: (22.000 - 22.500) data (500)
+Bin number 5 bounds: (22.500 - 23.000) data (500)
+Bin number 6 bounds: (23.000 - 23.500) data (500)
+Bin number 7 bounds: (23.500 - 24.000) data (500)
+Bin number 8 bounds: (24.000 - 24.500) data (500)
+Bin number 9 bounds: (24.500 - 25.000) data (500)
+Bin number 10 bounds: (25.000 - 25.500) data (0)
+Bin number 11 bounds: (25.500 - 26.000) data (0)
+Bin number 12 bounds: (26.000 - 26.500) data (0)
+Bin number 13 bounds: (26.500 - 27.000) data (0)
+Bin number 14 bounds: (27.000 - 27.500) data (0)
+Bin number 15 bounds: (27.500 - 28.000) data (0)
+Bin number 16 bounds: (28.000 - 28.500) data (0)
+Bin number 17 bounds: (28.500 - 29.000) data (0)
+Bin number 18 bounds: (29.000 - 29.500) data (0)
+Bin number 19 bounds: (29.500 - 30.000) data (0)
+
+---> TESTPOINT PASSED (psStats functions{Allocate and Perform Histogram with mask} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Calling psVectorHistogram() with various NULL inputs.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{Calling psVectorHistogram() with various NULL inputs.} | tst_psHist02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHist02.c                                             *
+*            TestPoint: psStats functions{Deallocate the psHistogram structure.}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{Deallocate the psHistogram structure.} | tst_psHist02.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix01.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix01.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix01.stdout	(revision 2163)
@@ -0,0 +1,45 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix01.c                                           *
+*            TestPoint: psMatrix{Create input and output images}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+7.000000 8.000000 9.000000 
+4.000000 5.000000 6.000000 
+1.000000 2.000000 3.000000 
+
+---> TESTPOINT PASSED (psMatrix{Create input and output images} | tst_psMatrix01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix01.c                                           *
+*            TestPoint: psMatrix{Transpose input image into output image}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+3.000000 6.000000 9.000000 
+2.000000 5.000000 8.000000 
+1.000000 4.000000 7.000000 
+
+---> TESTPOINT PASSED (psMatrix{Transpose input image into output image} | tst_psMatrix01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix01.c                                           *
+*            TestPoint: psMatrix{ranspose input image into auto allocated NULL output image} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+3.000000 6.000000 9.000000 
+2.000000 5.000000 8.000000 
+1.000000 4.000000 7.000000 
+
+---> TESTPOINT PASSED (psMatrix{ranspose input image into auto allocated NULL output image} | tst_psMatrix01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix01.c                                           *
+*            TestPoint: psMatrix{Free images and check for leaks}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Free images and check for leaks} | tst_psMatrix01.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix02.stderr
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix02.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix02.stderr	(revision 2163)
@@ -0,0 +1,12 @@
+<DATE><TIME>|<HOST>|E|psMatrixTranspose
+    Invalid operation: Pointer to inImage is same as outImage.
+<DATE><TIME>|<HOST>|E|psMatrixTranspose
+    Invalid operation: inImage or its data is NULL.
+<DATE><TIME>|<HOST>|E|psMatrixTranspose
+    Invalid operation: inImage not PS_TYPE_F64.
+<DATE><TIME>|<HOST>|E|psMatrixTranspose
+    Invalid operation: inImage not square array.
+<DATE><TIME>|<HOST>|E|psMatrixTranspose
+    Invalid operation: outImage not PS_TYPE_F64.
+<DATE><TIME>|<HOST>|E|psMatrixTranspose
+    Invalid operation: outImage not square array.
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix02.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix02.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix02.stdout	(revision 2163)
@@ -0,0 +1,66 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix02.c                                           *
+*            TestPoint: psMatrix{Input pointer same as output pointer}             *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: Pointer to inImage is same as outImage. *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Input pointer same as output pointer} | tst_psMatrix02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix02.c                                           *
+*            TestPoint: psMatrix{Null input psImage}                               *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: inImage or its data is NULL.            *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Null input psImage} | tst_psMatrix02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix02.c                                           *
+*            TestPoint: psMatrix{Incorrect type for input pointer}                 *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: |Invalid operation: inImage not PS_TYPE_F64.               *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Incorrect type for input pointer} | tst_psMatrix02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix02.c                                           *
+*            TestPoint: psMatrix{Matrix not square for input pointer}              *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: inImage not square array.               *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Matrix not square for input pointer} | tst_psMatrix02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix02.c                                           *
+*            TestPoint: psMatrix{Incorrect type for output pointer}                *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: outImage not PS_TYPE_F64.               *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Incorrect type for output pointer} | tst_psMatrix02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix02.c                                           *
+*            TestPoint: psMatrix{Matrix not square for output pointer}             *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: outImage not square array.              *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Matrix not square for output pointer} | tst_psMatrix02.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix03.stderr
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix03.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix03.stderr	(revision 2163)
@@ -0,0 +1,6 @@
+<DATE><TIME>|<HOST>|E|psMatrixLUD
+    Invalid operation: inImage or its data is NULL.
+<DATE><TIME>|<HOST>|E|psMatrixLUSolve
+    Invalid operation: inVector or its data is NULL.
+<DATE><TIME>|<HOST>|E|psMatrixLUSolve
+    Invalid operation: inImage or its data is NULL.
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix03.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix03.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix03.stdout	(revision 2163)
@@ -0,0 +1,82 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix03.c                                           *
+*            TestPoint: psMatrix{Create input and output images and vectors}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+3.000000 1.000000 -2.000000 
+4.000000 5.000000 6.000000 
+2.000000 4.000000 6.000000 
+
+18.000000
+24.000000
+4.000000
+
+---> TESTPOINT PASSED (psMatrix{Create input and output images and vectors} | tst_psMatrix03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix03.c                                           *
+*            TestPoint: psMatrix{Calculate LU matrix}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+0.500000 -0.545455 -0.545455 
+0.750000 -2.750000 -6.500000 
+4.000000 5.000000 6.000000 
+
+---> TESTPOINT PASSED (psMatrix{Calculate LU matrix} | tst_psMatrix03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix03.c                                           *
+*            TestPoint: psMatrix{Determine solution to matrix equation}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+4.000000
+-2.000000
+3.000000
+
+---> TESTPOINT PASSED (psMatrix{Determine solution to matrix equation} | tst_psMatrix03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix03.c                                           *
+*            TestPoint: psMatrix{Free input and output images and vectors}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Free input and output images and vectors} | tst_psMatrix03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix03.c                                           *
+*            TestPoint: psMatrix{Attempt to use null image input argument}         *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: inImage or its data is NULL.            *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Attempt to use null image input argument} | tst_psMatrix03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix03.c                                           *
+*            TestPoint: psMatrix{Attempt to use null input vector argument}        *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: inVector or its data is NULL.           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Attempt to use null input vector argument} | tst_psMatrix03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix03.c                                           *
+*            TestPoint: psMatrix{Attempt to use null LU image argument}            *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: inImage or its data is NULL.            *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Attempt to use null LU image argument} | tst_psMatrix03.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix04.stderr
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix04.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix04.stderr	(revision 2163)
@@ -0,0 +1,4 @@
+<DATE><TIME>|<HOST>|E|psMatrixInvert
+    Invalid operation: inImage or its data is NULL.
+<DATE><TIME>|<HOST>|E|psMatrixInvert
+    Invalid operation: determinant argument is NULL.
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix04.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix04.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix04.stdout	(revision 2163)
@@ -0,0 +1,67 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix04.c                                           *
+*            TestPoint: psMatrix{Create input and output images}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+3.000000 5.000000 7.000000 
+0.000000 1.000000 -1.000000 
+2.000000 4.000000 3.000000 
+
+---> TESTPOINT PASSED (psMatrix{Create input and output images} | tst_psMatrix04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix04.c                                           *
+*            TestPoint: psMatrix{Invert matrix and calculate determinant}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+-1.000000 0.666667 0.666667 
+-1.000000 1.666667 0.666667 
+4.000000 -4.333333 -2.333333 
+
+det = 3.000000
+
+---> TESTPOINT PASSED (psMatrix{Invert matrix and calculate determinant} | tst_psMatrix04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix04.c                                           *
+*            TestPoint: psMatrix{Calculate determinant only}                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+det = 3.000000
+
+---> TESTPOINT PASSED (psMatrix{Calculate determinant only} | tst_psMatrix04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix04.c                                           *
+*            TestPoint: psMatrix{Free input and output images}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Free input and output images} | tst_psMatrix04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix04.c                                           *
+*            TestPoint: psMatrix{Attempt to use null input image argument}         *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: inImage or its data is NULL.            *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Attempt to use null input image argument} | tst_psMatrix04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix04.c                                           *
+*            TestPoint: psMatrix{Attempt to use null input float argument}         *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: determinant argument is NULL.           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Attempt to use null input float argument} | tst_psMatrix04.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix05.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix05.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix05.stdout	(revision 2163)
@@ -0,0 +1,34 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix05.c                                           *
+*            TestPoint: psMatrix{Create input and output images}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+2.000000 3.000000 
+-1.000000 2.000000 
+
+4.000000 1.000000 
+0.000000 6.000000 
+
+---> TESTPOINT PASSED (psMatrix{Create input and output images} | tst_psMatrix05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix05.c                                           *
+*            TestPoint: psMatrix{Multiply images}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+8.000000 20.000000 
+-4.000000 11.000000 
+
+---> TESTPOINT PASSED (psMatrix{Multiply images} | tst_psMatrix05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix05.c                                           *
+*            TestPoint: psMatrix{Free input and output images}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Free input and output images} | tst_psMatrix05.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix06.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix06.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix06.stdout	(revision 2163)
@@ -0,0 +1,35 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix06.c                                           *
+*            TestPoint: psMatrix{Create input and output images}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+1.000000 0.500000 0.333333 0.250000 
+0.500000 0.333333 0.250000 0.200000 
+0.333333 0.250000 0.200000 0.166667 
+0.250000 0.200000 0.166667 0.142857 
+
+---> TESTPOINT PASSED (psMatrix{Create input and output images} | tst_psMatrix06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix06.c                                           *
+*            TestPoint: psMatrix{Calculate Eigenvectors}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+0.792608 0.582076 -0.179186 -0.029193 
+0.451923 -0.370502 0.741918 0.328712 
+0.322416 -0.509579 -0.100228 -0.791411 
+0.252161 -0.514048 -0.638283 0.514553 
+
+---> TESTPOINT PASSED (psMatrix{Calculate Eigenvectors} | tst_psMatrix06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix06.c                                           *
+*            TestPoint: psMatrix{Free input and output images}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Free input and output images} | tst_psMatrix06.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix07.stderr
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix07.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix07.stderr	(revision 2163)
@@ -0,0 +1,6 @@
+<DATE><TIME>|<HOST>|E|psMatrixToVector
+    Invalid operation: inImage or its data is NULL.
+<DATE><TIME>|<HOST>|E|psMatrixToVector
+    Image does not have dim with 1 col or 1 row: (2 x 2).
+<DATE><TIME>|<HOST>|E|psVectorToMatrix
+    Invalid operation: inVector or its data is NULL.
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix07.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix07.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMatrix07.stdout	(revision 2163)
@@ -0,0 +1,106 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Create input and output images and vectors}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+0.000000 
+1.000000 
+2.000000 
+
+0.000000 1.000000 2.000000 
+
+0.000000
+1.000000
+2.000000
+
+---> TESTPOINT PASSED (psMatrix{Create input and output images and vectors} | tst_psMatrix07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Convert matrix to PS_DIMEN_VECTOR vector}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+0.000000
+1.000000
+2.000000
+
+---> TESTPOINT PASSED (psMatrix{Convert matrix to PS_DIMEN_VECTOR vector} | tst_psMatrix07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Attempt to use null image input argument}         *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: inImage or its data is NULL.            *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Attempt to use null image input argument} | tst_psMatrix07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Convert matrix to PS_DIMEN_TRANSV vector}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+0.000000
+1.000000
+2.000000
+
+---> TESTPOINT PASSED (psMatrix{Convert matrix to PS_DIMEN_TRANSV vector} | tst_psMatrix07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Improper image size}                              *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Image does not have dim with 1 col or 1 row: (2 x 2).      *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Improper image size} | tst_psMatrix07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Convert PS_DIMEN_VECTOR vector to matrix}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+0.000000 
+1.000000 
+2.000000 
+
+---> TESTPOINT PASSED (psMatrix{Convert PS_DIMEN_VECTOR vector to matrix} | tst_psMatrix07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Attempt to use null input vector argument}        *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation: inVector or its data is NULL.           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Attempt to use null input vector argument} | tst_psMatrix07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Convert PS_DIMEN_TRANSV vector to matrix}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+0.000000 1.000000 2.000000 
+
+---> TESTPOINT PASSED (psMatrix{Convert PS_DIMEN_TRANSV vector to matrix} | tst_psMatrix07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrix07.c                                           *
+*            TestPoint: psMatrix{Free input and output images and vectors}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrix{Free input and output images and vectors} | tst_psMatrix07.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic01.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic01.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic01.stdout	(revision 2163)
@@ -0,0 +1,1156 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: +
+Input:
+10 10 
+10 10 
+10 10 
+
+10 10 
+10 10 
+10 10 
+
+Output:
+20 20 
+20 20 
+20 20 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: +
+Input:
+10.000000 10.000000 
+10.000000 10.000000 
+10.000000 10.000000 
+
+10.000000 10.000000 
+10.000000 10.000000 
+10.000000 10.000000 
+
+Output:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: +
+Input:
+10.000000 10.000000 
+10.000000 10.000000 
+10.000000 10.000000 
+
+10.000000 10.000000 
+10.000000 10.000000 
+10.000000 10.000000 
+
+Output:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: +
+Input:
+10.000000+10.000000i 10.000000+10.000000i 
+10.000000+10.000000i 10.000000+10.000000i 
+10.000000+10.000000i 10.000000+10.000000i 
+
+10.000000+10.000000i 10.000000+10.000000i 
+10.000000+10.000000i 10.000000+10.000000i 
+10.000000+10.000000i 10.000000+10.000000i 
+
+Output:
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: -
+Input:
+20 20 
+20 20 
+20 20 
+
+10 10 
+10 10 
+10 10 
+
+Output:
+10 10 
+10 10 
+10 10 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: -
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+10.000000 10.000000 
+10.000000 10.000000 
+10.000000 10.000000 
+
+Output:
+10.000000 10.000000 
+10.000000 10.000000 
+10.000000 10.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: -
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+10.000000 10.000000 
+10.000000 10.000000 
+10.000000 10.000000 
+
+Output:
+10.000000 10.000000 
+10.000000 10.000000 
+10.000000 10.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: *
+Input:
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+
+10.000000+10.000000i 10.000000+10.000000i 
+10.000000+10.000000i 10.000000+10.000000i 
+10.000000+10.000000i 10.000000+10.000000i 
+
+Output:
+0.000000+400.000000i 0.000000+400.000000i 
+0.000000+400.000000i 0.000000+400.000000i 
+0.000000+400.000000i 0.000000+400.000000i 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: *
+Input:
+20 20 
+20 20 
+20 20 
+
+10 10 
+10 10 
+10 10 
+
+Output:
+200 200 
+200 200 
+200 200 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: *
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+10.000000 10.000000 
+10.000000 10.000000 
+10.000000 10.000000 
+
+Output:
+200.000000 200.000000 
+200.000000 200.000000 
+200.000000 200.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: *
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+10.000000 10.000000 
+10.000000 10.000000 
+10.000000 10.000000 
+
+Output:
+200.000000 200.000000 
+200.000000 200.000000 
+200.000000 200.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: *
+Input:
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+
+10.000000+10.000000i 10.000000+10.000000i 
+10.000000+10.000000i 10.000000+10.000000i 
+10.000000+10.000000i 10.000000+10.000000i 
+
+Output:
+0.000000+400.000000i 0.000000+400.000000i 
+0.000000+400.000000i 0.000000+400.000000i 
+0.000000+400.000000i 0.000000+400.000000i 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: /
+Input:
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+
+10.000000+10.000000i 10.000000+10.000000i 
+10.000000+10.000000i 10.000000+10.000000i 
+10.000000+10.000000i 10.000000+10.000000i 
+
+Output:
+2.000000+0.000000i 2.000000+0.000000i 
+2.000000+0.000000i 2.000000+0.000000i 
+2.000000+0.000000i 2.000000+0.000000i 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: /
+Input:
+20 20 
+20 20 
+20 20 
+
+10 10 
+10 10 
+10 10 
+
+Output:
+2 2 
+2 2 
+2 2 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: /
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+10.000000 10.000000 
+10.000000 10.000000 
+10.000000 10.000000 
+
+Output:
+2.000000 2.000000 
+2.000000 2.000000 
+2.000000 2.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: /
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+10.000000 10.000000 
+10.000000 10.000000 
+10.000000 10.000000 
+
+Output:
+2.000000 2.000000 
+2.000000 2.000000 
+2.000000 2.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: /
+Input:
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+
+10.000000+10.000000i 10.000000+10.000000i 
+10.000000+10.000000i 10.000000+10.000000i 
+10.000000+10.000000i 10.000000+10.000000i 
+
+Output:
+2.000000+0.000000i 2.000000+0.000000i 
+2.000000+0.000000i 2.000000+0.000000i 
+2.000000+0.000000i 2.000000+0.000000i 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-matrix psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: +
+Input:
+10 10 
+10 10 
+10 10 
+
+5 5 5 
+
+Output:
+15 15 
+15 15 
+15 15 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: +
+Input:
+10.000000 10.000000 
+10.000000 10.000000 
+10.000000 10.000000 
+
+5.000000 5.000000 5.000000 
+
+Output:
+15.000000 15.000000 
+15.000000 15.000000 
+15.000000 15.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: +
+Input:
+10.000000 10.000000 
+10.000000 10.000000 
+10.000000 10.000000 
+
+5.000000 5.000000 5.000000 
+
+Output:
+15.000000 15.000000 
+15.000000 15.000000 
+15.000000 15.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: +
+Input:
+10.000000+10.000000i 10.000000+10.000000i 
+10.000000+10.000000i 10.000000+10.000000i 
+10.000000+10.000000i 10.000000+10.000000i 
+
+5.000000+5.000000i 5.000000+5.000000i 5.000000+5.000000i 
+
+Output:
+15.000000+15.000000i 15.000000+15.000000i 
+15.000000+15.000000i 15.000000+15.000000i 
+15.000000+15.000000i 15.000000+15.000000i 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: -
+Input:
+20 20 
+20 20 
+20 20 
+
+5 5 5 
+
+Output:
+15 15 
+15 15 
+15 15 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: -
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+5.000000 5.000000 5.000000 
+
+Output:
+15.000000 15.000000 
+15.000000 15.000000 
+15.000000 15.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: -
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+5.000000 5.000000 5.000000 
+
+Output:
+15.000000 15.000000 
+15.000000 15.000000 
+15.000000 15.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: *
+Input:
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+
+5.000000+5.000000i 5.000000+5.000000i 5.000000+5.000000i 
+
+Output:
+0.000000+200.000000i 0.000000+200.000000i 
+0.000000+200.000000i 0.000000+200.000000i 
+0.000000+200.000000i 0.000000+200.000000i 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: *
+Input:
+20 20 
+20 20 
+20 20 
+
+5 5 5 
+
+Output:
+100 100 
+100 100 
+100 100 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: *
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+5.000000 5.000000 5.000000 
+
+Output:
+100.000000 100.000000 
+100.000000 100.000000 
+100.000000 100.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: *
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+5.000000 5.000000 5.000000 
+
+Output:
+100.000000 100.000000 
+100.000000 100.000000 
+100.000000 100.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: *
+Input:
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+
+5.000000+5.000000i 5.000000+5.000000i 5.000000+5.000000i 
+
+Output:
+0.000000+200.000000i 0.000000+200.000000i 
+0.000000+200.000000i 0.000000+200.000000i 
+0.000000+200.000000i 0.000000+200.000000i 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: /
+Input:
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+
+5.000000+5.000000i 5.000000+5.000000i 5.000000+5.000000i 
+
+Output:
+4.000000+0.000000i 4.000000+0.000000i 
+4.000000+0.000000i 4.000000+0.000000i 
+4.000000+0.000000i 4.000000+0.000000i 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: /
+Input:
+20 20 
+20 20 
+20 20 
+
+5 5 5 
+
+Output:
+4 4 
+4 4 
+4 4 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: /
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+5.000000 5.000000 5.000000 
+
+Output:
+4.000000 4.000000 
+4.000000 4.000000 
+4.000000 4.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: /
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+5.000000 5.000000 5.000000 
+
+Output:
+4.000000 4.000000 
+4.000000 4.000000 
+4.000000 4.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-vector psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: /
+Input:
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+
+5.000000+5.000000i 5.000000+5.000000i 5.000000+5.000000i 
+
+Output:
+4.000000+0.000000i 4.000000+0.000000i 
+4.000000+0.000000i 4.000000+0.000000i 
+4.000000+0.000000i 4.000000+0.000000i 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-vector psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: +
+Input:
+10 10 
+10 10 
+10 10 
+
+5 
+
+Output:
+15 15 
+15 15 
+15 15 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: +
+Input:
+10.000000 10.000000 
+10.000000 10.000000 
+10.000000 10.000000 
+
+5.000000 
+
+Output:
+15.000000 15.000000 
+15.000000 15.000000 
+15.000000 15.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: +
+Input:
+10.000000 10.000000 
+10.000000 10.000000 
+10.000000 10.000000 
+
+5.000000 
+
+Output:
+15.000000 15.000000 
+15.000000 15.000000 
+15.000000 15.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: +
+Input:
+10.000000+10.000000i 10.000000+10.000000i 
+10.000000+10.000000i 10.000000+10.000000i 
+10.000000+10.000000i 10.000000+10.000000i 
+
+5.000000+5.000000i 
+
+Output:
+15.000000+15.000000i 15.000000+15.000000i 
+15.000000+15.000000i 15.000000+15.000000i 
+15.000000+15.000000i 15.000000+15.000000i 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: -
+Input:
+20 20 
+20 20 
+20 20 
+
+5 
+
+Output:
+15 15 
+15 15 
+15 15 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: -
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+5.000000 
+
+Output:
+15.000000 15.000000 
+15.000000 15.000000 
+15.000000 15.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: -
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+5.000000 
+
+Output:
+15.000000 15.000000 
+15.000000 15.000000 
+15.000000 15.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: *
+Input:
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+
+5.000000+5.000000i 
+
+Output:
+0.000000+200.000000i 0.000000+200.000000i 
+0.000000+200.000000i 0.000000+200.000000i 
+0.000000+200.000000i 0.000000+200.000000i 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: *
+Input:
+20 20 
+20 20 
+20 20 
+
+5 
+
+Output:
+100 100 
+100 100 
+100 100 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: *
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+5.000000 
+
+Output:
+100.000000 100.000000 
+100.000000 100.000000 
+100.000000 100.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: *
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+5.000000 
+
+Output:
+100.000000 100.000000 
+100.000000 100.000000 
+100.000000 100.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: *
+Input:
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+
+5.000000+5.000000i 
+
+Output:
+0.000000+200.000000i 0.000000+200.000000i 
+0.000000+200.000000i 0.000000+200.000000i 
+0.000000+200.000000i 0.000000+200.000000i 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: /
+Input:
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+
+5.000000+5.000000i 
+
+Output:
+4.000000+0.000000i 4.000000+0.000000i 
+4.000000+0.000000i 4.000000+0.000000i 
+4.000000+0.000000i 4.000000+0.000000i 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: /
+Input:
+20 20 
+20 20 
+20 20 
+
+5 
+
+Output:
+4 4 
+4 4 
+4 4 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: /
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+5.000000 
+
+Output:
+4.000000 4.000000 
+4.000000 4.000000 
+4.000000 4.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: /
+Input:
+20.000000 20.000000 
+20.000000 20.000000 
+20.000000 20.000000 
+
+5.000000 
+
+Output:
+4.000000 4.000000 
+4.000000 4.000000 
+4.000000 4.000000 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic01.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: /
+Input:
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+20.000000+20.000000i 20.000000+20.000000i 
+
+5.000000+5.000000i 
+
+Output:
+4.000000+0.000000i 4.000000+0.000000i 
+4.000000+0.000000i 4.000000+0.000000i 
+4.000000+0.000000i 4.000000+0.000000i 
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix-scalar psBinaryOp} | tst_psMatrixVectorArithmetic01.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic02.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic02.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic02.stdout	(revision 2163)
@@ -0,0 +1,1700 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: abs
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: abs
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: abs
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: abs
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: exp
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: exp
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: exp
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: exp
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: ln
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: ln
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: ln
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: ln
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: ten
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: ten
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: ten
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: ten
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: log
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: log
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: log
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: log
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: sin
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: sin
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: sin
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: sin
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dsin
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dsin
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dsin
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dsin
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: cos
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: cos
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: cos
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: cos
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dcos
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dcos
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dcos
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dcos
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: tan
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: tan
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: tan
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: tan
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dtan
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dtan
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dtan
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dtan
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: asin
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: asin
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: asin
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: asin
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dasin
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dasin
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dasin
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dasin
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: acos
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: acos
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: acos
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: acos
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dacos
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dacos
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dacos
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dacos
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: atan
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: atan
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: atan
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: atan
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: datan
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: datan
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: datan
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test matrix psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: datan
+
+
+
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test matrix psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: abs
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: abs
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: abs
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: abs
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: exp
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: exp
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: exp
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: exp
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: ln
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: ln
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: ln
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: ln
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: ten
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: ten
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: ten
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: ten
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: log
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: log
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: log
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: log
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: sin
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: sin
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: sin
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: sin
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dsin
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dsin
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dsin
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dsin
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: cos
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: cos
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: cos
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: cos
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dcos
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dcos
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dcos
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dcos
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: tan
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: tan
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: tan
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: tan
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dtan
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dtan
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dtan
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dtan
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: asin
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: asin
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: asin
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: asin
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dasin
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dasin
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dasin
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dasin
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: acos
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: acos
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: acos
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: acos
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dacos
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dacos
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dacos
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: dacos
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: atan
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: atan
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: atan
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: atan
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: datan
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: datan
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: datan
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic02.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Test vector psUnaryOp}            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Operation: datan
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Test vector psUnaryOp} | tst_psMatrixVectorArithmetic02.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic03.stderr
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic03.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic03.stderr	(revision 2163)
@@ -0,0 +1,34 @@
+<DATE><TIME>|<HOST>|E|psBinaryOp
+    : Line <LINENO> - Null in1 argument
+<DATE><TIME>|<HOST>|E|psBinaryOp
+    : Line <LINENO> - Null in2 argument
+<DATE><TIME>|<HOST>|E|psBinaryOp
+    : Line <LINENO> - Null op argument
+<DATE><TIME>|<HOST>|E|psUnaryOp
+    : Line <LINENO> - Null in argument
+<DATE><TIME>|<HOST>|E|psUnaryOp
+    : Line <LINENO> - Null op argument
+<DATE><TIME>|<HOST>|E|psBinaryOp
+    : Line <LINENO> - Element types for arguments inconsistent: (1028, 1032)
+<DATE><TIME>|<HOST>|E|psBinaryOp
+    : Inconsistent element count: numRows: 2 vs 3 numCols: 2 vs 3
+<DATE><TIME>|<HOST>|E|psBinaryOp
+    : Inconsistent element count: 2 vs 3
+<DATE><TIME>|<HOST>|E|psBinaryOp
+    : Inconsistent element count: 2 vs 3
+<DATE><TIME>|<HOST>|E|psLib.collections.psVectorRecycle
+    The input psVector must have a vector dimension type.
+<DATE><TIME>|<HOST>|E|psUnaryOp
+    Couldn't create a proper output psVector.
+<DATE><TIME>|<HOST>|E|psBinaryOp
+    : Minimum operation not supported for complex numbers
+<DATE><TIME>|<HOST>|E|psBinaryOp
+    : Maximum operation not supported for complex numbers
+<DATE><TIME>|<HOST>|E|psBinaryOp
+    : Invalid operation: yarg
+<DATE><TIME>|<HOST>|E|psUnaryOp
+    : Invalid operation: yarg
+<DATE><TIME>|<HOST>|E|psBinaryOp
+    : Line <LINENO> - Null in2 argument
+<DATE><TIME>|<HOST>|E|psBinaryOp
+    : Line <LINENO> - PS_DIMEN_OTHER not allowed for arguments: (4, 1)
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic03.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic03.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMatrixVectorArithmetic03.stdout	(revision 2163)
@@ -0,0 +1,88 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Check for NULL arguments}         *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null XXX argument                                          *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Check for NULL arguments} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Inconsistent element types}       *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Element types for arguments inconsistent                   *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Inconsistent element types} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Inconsistent element count}       *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Inconsistent element count                                 *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Inconsistent element count} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Inconsistent dimensionality}      *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Dimensionality for arguments inconsistent                  *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Inconsistent dimensionality} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Use min with complex numbers}     *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Minimum operation not supported for complex numbers        *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Use min with complex numbers} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Use max with complex numbers}     *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Maximum operation not supported for complex numbers        *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Use max with complex numbers} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Invalid operation}                *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation                                          *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Invalid operation} | tst_psMatrixVectorArithmetic03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMatrixVectorArithmetic03.c                           *
+*            TestPoint: psMatrixVectorArithmetic{Invalid input}                    *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Invalid operation                                          *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMatrixVectorArithmetic{Invalid input} | tst_psMatrixVectorArithmetic03.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04.stderr
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04.stderr	(revision 2163)
@@ -0,0 +1,4 @@
+<DATE><TIME>|<HOST>|I|t03
+    Following should generate an error for null input polynomial.
+<DATE><TIME>|<HOST>|E|psVectorFitPolynomial1D
+    Unallowable operation: myPoly or its coeffs is NULL.
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04.stdout	(revision 2163)
@@ -0,0 +1,36 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMinimize04.c                                         *
+*            TestPoint: psMinimize functions{psVectorFitPolynomial1D(): equal difference in variable yE *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMinimize functions{psVectorFitPolynomial1D(): equal differences in variable yErr} | tst_psMinimize04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMinimize04.c                                         *
+*            TestPoint: psMinimize functions{psVectorFitPolynomial1D(): yErr is NULL} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMinimize functions{psVectorFitPolynomial1D(): yErr is NULL} | tst_psMinimize04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMinimize04.c                                         *
+*            TestPoint: psMinimize functions{psVectorFitPolynomial1D(): x, yErr is NULL} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMinimize functions{psVectorFitPolynomial1D(): x, yErr is NULL} | tst_psMinimize04.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMinimize04.c                                         *
+*            TestPoint: psMinimize functions{psVectorFitPolynomial1D(): all inputs are NULL} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMinimize functions{psVectorFitPolynomial1D(): all inputs are NULL} | tst_psMinimize04.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04_F32.stderr
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04_F32.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04_F32.stderr	(revision 2163)
@@ -0,0 +1,4 @@
+<DATE><TIME>|<HOST>|I|t03
+    Following should generate error for null arguments.
+<DATE><TIME>|<HOST>|E|psVectorFitPolynomial1D
+    Unallowable operation: myPoly or its coeffs is NULL.
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04_F32.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04_F32.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04_F32.stdout	(revision 2163)
@@ -0,0 +1,36 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMinimize04_F32.c                                     *
+*            TestPoint: psMinimize functions{psVectorFitPolynomial1D(): equal errors in yErr} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMinimize functions{psVectorFitPolynomial1D(): equal errors in yErr} | tst_psMinimize04_F32.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMinimize04_F32.c                                     *
+*            TestPoint: psMinimize functions{psVectorFitPolynomial1D(): yErr is NULL} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMinimize functions{psVectorFitPolynomial1D(): yErr is NULL} | tst_psMinimize04_F32.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMinimize04_F32.c                                     *
+*            TestPoint: psMinimize functions{psVectorFitPolynomial1D(): x, yErr is NULL} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMinimize functions{psVectorFitPolynomial1D(): x, yErr is NULL} | tst_psMinimize04_F32.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMinimize04_F32.c                                     *
+*            TestPoint: psMinimize functions{psVectorFitPolynomial1D(): all inputs are NULL} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMinimize functions{psVectorFitPolynomial1D(): all inputs are NULL} | tst_psMinimize04_F32.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04b.stderr
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04b.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04b.stderr	(revision 2163)
@@ -0,0 +1,4 @@
+<DATE><TIME>|<HOST>|I|t03
+    Following should generate an error for null arguments.
+<DATE><TIME>|<HOST>|E|psVectorFitPolynomial1D
+    Unallowable operation: myPoly or its coeffs is NULL.
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04b.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04b.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04b.stdout	(revision 2163)
@@ -0,0 +1,36 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMinimize04b.c                                        *
+*            TestPoint: psMinimize functions{psVectorFitPolynomial1D(): CHEB, equal errors in yErr} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMinimize functions{psVectorFitPolynomial1D(): CHEB, equal errors in yErr} | tst_psMinimize04b.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMinimize04b.c                                        *
+*            TestPoint: psMinimize functions{psVectorFitPolynomial1D(): CHEB, yErr is NULL} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMinimize functions{psVectorFitPolynomial1D(): CHEB, yErr is NULL} | tst_psMinimize04b.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMinimize04b.c                                        *
+*            TestPoint: psMinimize functions{psVectorFitPolynomial1D(): CHEB, x, yErr is NULL} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMinimize functions{psVectorFitPolynomial1D(): CHEB, x, yErr is NULL} | tst_psMinimize04b.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMinimize04b.c                                        *
+*            TestPoint: psMinimize functions{psVectorFitPolynomial1D(): CHEB, yErr is NULL} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMinimize functions{psVectorFitPolynomial1D(): CHEB, yErr is NULL} | tst_psMinimize04b.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04b_F32.stderr
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04b_F32.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04b_F32.stderr	(revision 2163)
@@ -0,0 +1,4 @@
+<DATE><TIME>|<HOST>|I|t03
+    Following should generate error for null arguments.
+<DATE><TIME>|<HOST>|E|psVectorFitPolynomial1D
+    Unallowable operation: myPoly or its coeffs is NULL.
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04b_F32.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04b_F32.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize04b_F32.stdout	(revision 2163)
@@ -0,0 +1,36 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMinimize04b_F32.c                                    *
+*            TestPoint: psMinimize functions{psVectorFitPolynomial1D(): CHEB, equal errors in yErr} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMinimize functions{psVectorFitPolynomial1D(): CHEB, equal errors in yErr} | tst_psMinimize04b_F32.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMinimize04b_F32.c                                    *
+*            TestPoint: psMinimize functions{psVectorFitPolynomial1D(): CHEB, yErr is NULL} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMinimize functions{psVectorFitPolynomial1D(): CHEB, yErr is NULL} | tst_psMinimize04b_F32.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMinimize04b_F32.c                                    *
+*            TestPoint: psMinimize functions{psVectorFitPolynomial1D(): CHEB, x, yErr is NULL} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMinimize functions{psVectorFitPolynomial1D(): CHEB, x, yErr is NULL} | tst_psMinimize04b_F32.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMinimize04b_F32.c                                    *
+*            TestPoint: psMinimize functions{psVectorFitPolynomial1D(): CHEB, yErr is NULL} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psMinimize functions{psVectorFitPolynomial1D(): CHEB, yErr is NULL} | tst_psMinimize04b_F32.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize05.stderr
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize05.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psMinimize05.stderr	(revision 2163)
@@ -0,0 +1,16 @@
+<DATE><TIME>|<HOST>|I|t02
+    Following should generate error for null minimize.
+<DATE><TIME>|<HOST>|E|psMinimizePowell
+    Unallowable operation: min is NULL.
+<DATE><TIME>|<HOST>|I|t02
+    Following should generate error for null parameter vector
+<DATE><TIME>|<HOST>|E|psMinimizePowell
+    Unallowable operation: params or its data is NULL.
+<DATE><TIME>|<HOST>|I|t02
+    Following should generate error for null coords.
+<DATE><TIME>|<HOST>|E|psMinimizePowell
+    Unallowable operation: coords is NULL.
+<DATE><TIME>|<HOST>|I|t02
+    Following should generate error for null function
+<DATE><TIME>|<HOST>|E|psMinimizePowell
+    Unallowable operation: func is NULL.
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psStats00.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psStats00.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psStats00.stdout	(revision 2163)
@@ -0,0 +1,62 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats00.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_MEAN: no vector mask}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The expected mean was 4.500000; the calculated mean was 4.500000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_MEAN: no vector mask} | tst_psStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats00.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_MEAN: with vector mask=1} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with last N/2 elements masked.
+The expected mean was 2.000000; the calculated mean was 2.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_MEAN: with vector mask=1} | tst_psStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats00.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_MEAN: with vector mask=2} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with last N/2 elements masked.
+The expected mean was 2.000000; the calculated mean was 2.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_MEAN: with vector mask=2} | tst_psStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats00.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_MEAN: with vector mask=3} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with last N/2 elements masked.
+The expected mean was 2.000000; the calculated mean was 2.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_MEAN: with vector mask=3} | tst_psStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats00.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_MEAN: NULL inputs}        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_MEAN: NULL inputs} | tst_psStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats00.c                                            *
+*            TestPoint: psStats functions{psStats(): deallocating memory}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector functions{psStats(): deallocating memory} | tst_psStats00.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psStats01.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psStats01.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psStats01.stdout	(revision 2163)
@@ -0,0 +1,36 @@
+Masking element 5
+Masking element 6
+Masking element 7
+Masking element 8
+Masking element 9
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats01.c                                            *
+*            TestPoint: psStats functions{PS_STAT_MAX: no vector mask}             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The expected max was 9.000000; the calculated max was 9.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_MAX: no vector mask} | tst_psStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats01.c                                            *
+*            TestPoint: psStats functions{PS_STAT_MAX: with vector mask}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with last N/2 elements masked.
+The expected max was 4.000000; the calculated max was 4.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_MAX: with vector mask} | tst_psStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats01.c                                            *
+*            TestPoint: psStats functions{psStats(): deallocating memory}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector functions{psStats(): deallocating memory} | tst_psStats01.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psStats02.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psStats02.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psStats02.stdout	(revision 2163)
@@ -0,0 +1,31 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats02.c                                            *
+*            TestPoint: psStats functions{PS_STAT_MIN: no vector mask}             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The expected min was 0.000000; the calculated min was 0.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_MIN: no vector mask} | tst_psStats02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats02.c                                            *
+*            TestPoint: psStats functions{PS_STAT_MIN: with vector mask}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with last N/2 elements masked.
+The expected min was 5.000000; the calculated min was 5.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_MIN: with vector mask} | tst_psStats02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats02.c                                            *
+*            TestPoint: psStats functions{psStats(): deallocating memory}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector functions{psStats(): deallocating memory} | tst_psStats02.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psStats03.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psStats03.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psStats03.stdout	(revision 2163)
@@ -0,0 +1,31 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats03.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_MEDIAN: no vector mask}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The expected median was 2058.000000.  The calculated median was 2058.000000.
+
+---> TESTPOINT PASSED (psStats functions{PS_STAT_SAMPLE_MEDIAN: no vector mask} | tst_psStats03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats03.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_MEDIAN: with vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with last N/2 elements masked.
+The expected median was 1028.500000.  The calculated median was 1028.500000.
+
+---> TESTPOINT PASSED (psStats functions{PS_STAT_SAMPLE_MEDIAN: with vector mask} | tst_psStats03.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats03.c                                            *
+*            TestPoint: psStats functions{psStats(): deallocating memory}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{psStats(): deallocating memory} | tst_psStats03.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psStats05.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psStats05.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psStats05.stdout	(revision 2163)
@@ -0,0 +1,18 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats05.c                                            *
+*            TestPoint: psStats functions{Allocate the psStats structure.}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{Allocate the psStats structure.} | tst_psStats05.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats05.c                                            *
+*            TestPoint: psStats functions{Deallocate the psStats structure.}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psStats functions{Deallocate the psStats structure.} | tst_psStats05.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psStats06.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psStats06.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psStats06.stdout	(revision 2163)
@@ -0,0 +1,31 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats06.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_STDEV: no vector mask}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The expected stdev was 4.472136; the calculated stdev was 4.472136
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_STDEV: no vector mask} | tst_psStats06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats06.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_STDEV: with vector mask}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with last N/2 elements masked.
+The expected stdev was 2.160247; the calculated stdev was 2.160247
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_STDEV: with vector mask} | tst_psStats06.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats06.c                                            *
+*            TestPoint: psStats functions{psStats(): deallocating memory}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector functions{psStats(): deallocating memory} | tst_psStats06.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psStats07.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psStats07.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psStats07.stdout	(revision 2163)
@@ -0,0 +1,81 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust mean: no vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+(LQBinNum, UQBinNum, maxBinNum) is (15, 35, 27)
+The expected Mean was 32.00; the calculated Mean was 32.59
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust mean: no vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust Median: no vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected Median was 32.00; the calculated Median was 32.49
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust Median: no vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust Mode: no vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected Mode was 32.00; the calculated Mode was 32.59
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust Mode: no vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust Stdev: no vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected Stdev was 0.66; the calculated Stdev was 0.66
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust Stdev: no vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: lower quartile: no vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected LQ was 30.80; the calculated LQ was 30.02
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: lower quartile: no vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: upper quartile: no vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected UQ was 33.20; the calculated UQ was 34.33
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: lower quartile: no vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust N50: no vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected N50 was 143; the calculated N50 was 143
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust N50: no vector mask} | tst_psStats07.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats07.c                                            *
+*            TestPoint: psStats functions{PS_STAT_ROBUST_STATS: robust Nfit: no vector mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The expected Nfit was 80; the calculated Nfit was 80
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_ROBUST_STATS: robust Nfit: no vector mask} | tst_psStats07.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psStats08.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psStats08.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psStats08.stdout	(revision 2163)
@@ -0,0 +1,53 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats08.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_LQ: no vector mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The expected sampleLQ was 50.000000; the calculated sampleLQ was 50.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_LQ: no vector mask} | tst_psStats08.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats08.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_UQ: no vector mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The expected sampleUQ was 150.000000; the calculated sampleUQ was 150.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_UQ: no vector mask} | tst_psStats08.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats08.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_LQ: with vector mask}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with elements masked.
+The expected sampleLQ was 25.000000; the calculated sampleLQ was 25.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_LQ: with vector mask} | tst_psStats08.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats08.c                                            *
+*            TestPoint: psStats functions{PS_STAT_SAMPLE_UQ: with vector mask}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with elements masked.
+The expected sampleUQ was 75.000000; the calculated sampleUQ was 75.000000
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_SAMPLE_UQ: with vector mask} | tst_psStats08.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats08.c                                            *
+*            TestPoint: psStats functions{psStats(): deallocating memory}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector functions{psStats(): deallocating memory} | tst_psStats08.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psStats09.stdout
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psStats09.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psStats09.stdout	(revision 2163)
@@ -0,0 +1,53 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats09.c                                            *
+*            TestPoint: psStats functions{PS_STAT_CLIPPED_MEAN: no vector mask}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The calculated clippedMean was 29.945370
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_CLIPPED_MEAN/STDEV: no vector mask} | tst_psStats09.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats09.c                                            *
+*            TestPoint: psStats functions{PS_STAT_CLIPPED_STDEV: no vector mask}   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with no elements masked.
+The calculated clippedStdev was 0.577927
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_CLIPPED_MEAN/STDEV: no vector mask} | tst_psStats09.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats09.c                                            *
+*            TestPoint: psStats functions{PS_STAT_CLIPPED_MEAN: vector mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with elements masked.
+The calculated clippedMean was 29.945370
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_CLIPPED_MEAN/STDEV: vector mask} | tst_psStats09.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats09.c                                            *
+*            TestPoint: psStats functions{PS_STAT_CLIPPED_STDEV: vector mask}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Called psVectorStats() on a vector with elements masked.
+The calculated clippedStdev was 0.285787
+
+---> TESTPOINT PASSED (psVector functions{PS_STAT_CLIPPED_MEAN/STDEV: vector mask} | tst_psStats09.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStats09.c                                            *
+*            TestPoint: psStats functions{psStats(): deallocating memory}          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psVector functions{psStats(): deallocating memory} | tst_psStats09.c)
+
Index: /branches/rel3/psLib/test/dataManip/verified/tst_psVectorFFT.stderr
===================================================================
--- /branches/rel3/psLib/test/dataManip/verified/tst_psVectorFFT.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/dataManip/verified/tst_psVectorFFT.stderr	(revision 2163)
@@ -0,0 +1,49 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorFFT.c                                          *
+*            TestPoint: psFFT{psVectorFFT}                                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFFT{psVectorFFT} | tst_psVectorFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorFFT.c                                          *
+*            TestPoint: psFFT{psVectorRealImaginary}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFFT{psVectorRealImaginary} | tst_psVectorFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorFFT.c                                          *
+*            TestPoint: psFFT{psVectorComplex}                                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testVectorComplex
+    Following should be an error (type mismatch).
+<DATE><TIME>|<HOST>|E|psLib.dataManip.psVectorComplex
+    Real psVector type, psF32, and imaginary psVector type, psF64, must be the same.
+
+---> TESTPOINT PASSED (psFFT{psVectorComplex} | tst_psVectorFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorFFT.c                                          *
+*            TestPoint: psFFT{psVectorConjugate}                                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFFT{psVectorConjugate} | tst_psVectorFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psVectorFFT.c                                          *
+*            TestPoint: psFFT{psVectorPowerSpectrum}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFFT{psVectorPowerSpectrum} | tst_psVectorFFT.c)
+
Index: /branches/rel3/psLib/test/image/.cvsignore
===================================================================
--- /branches/rel3/psLib/test/image/.cvsignore	(revision 2163)
+++ /branches/rel3/psLib/test/image/.cvsignore	(revision 2163)
@@ -0,0 +1,11 @@
+temp
+tst_psImage
+tst_psImageExtraction
+tst_psImageFFT
+tst_psImageManip
+tst_psImageStats00
+tst_psImageStats01
+tst_psImageStats02
+tst_psImageStats03
+tst_psImageConvolve
+tst_psImageIO
Index: /branches/rel3/psLib/test/image/Makefile
===================================================================
--- /branches/rel3/psLib/test/image/Makefile	(revision 2163)
+++ /branches/rel3/psLib/test/image/Makefile	(revision 2163)
@@ -0,0 +1,53 @@
+################################################################################
+##
+##  Makefile:   test/collections
+##
+##  $Revision: 1.5 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-10-15 19:10:51 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+##
+###############################################################################
+
+ifndef prefix
+    export prefix=$(shell cd ../..;pwd)
+endif
+
+include ../../src/Makefile.Globals
+
+CFLAGS := -I../../include $(CFLAGS)
+LDFLAGS := -L../../lib -lpslib -lpstest $(LDFLAGS)
+
+TARGET = tst_psImage \
+tst_psImageFFT \
+tst_psImageManip \
+tst_psImageStats00 \
+tst_psImageStats01 \
+tst_psImageStats02 \
+tst_psImageStats03 \
+tst_psImageExtraction \
+tst_psImageConvolve \
+tst_psImageIO
+
+OBJS = $(addsuffix .o,$(TARGET))
+
+all: $(TARGET)
+
+clean:
+	@echo "    Deleting executable and binary files for 'test/collections'"
+	$(RM) $(OBJS)
+
+distclean: clean
+	$(RM) $(TARGET)
+
+install: $(testbindir) $(testbindir)/verified $(TARGET)
+	install $(TARGET) $(testbindir)
+	install verified/*.fits verified/*.stderr verified/*.stdout $(testbindir)/verified
+
+$(testbindir):
+	mkdir -p $(testbindir)
+
+$(testbindir)/verified:
+	mkdir -p $(testbindir)/verified
+
+
Index: /branches/rel3/psLib/test/image/tst_psImage.c
===================================================================
--- /branches/rel3/psLib/test/image/tst_psImage.c	(revision 2163)
+++ /branches/rel3/psLib/test/image/tst_psImage.c	(revision 2163)
@@ -0,0 +1,395 @@
+/** @file  tst_psImage.c
+ *
+ *  @brief Contains the tests for psImage.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.27 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-29 20:17:58 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <math.h>
+#include <float.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "psTest.h"
+#include "pslib.h"
+#include "psType.h"
+
+static int testImageAlloc(void);
+static int testImageCopy(void);
+
+testDescription tests[] = {
+                              {testImageAlloc,546,"psImageAlloc",0,false},
+                              {testImageAlloc,548,"psImageFree",0,true},
+                              {testImageCopy,551,"psImageCopy",0,false},
+                              {NULL}
+                          };
+
+int main(int argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    return ! runTestSuite(stderr,"psImage",tests,argc,argv);
+}
+
+int testImageAlloc(void)
+{
+    psImage* image = NULL;
+    unsigned int sizes = 6;
+    unsigned int numCols[] = {
+                                 0,1,1,100,100,150
+                             };
+    unsigned int numRows[] = {
+                                 0,1,100,1,150,100
+                             };
+    unsigned int types = 13;
+    psElemType type[] = { PS_TYPE_S8, PS_TYPE_S16, PS_TYPE_S32, PS_TYPE_S64,
+                          PS_TYPE_U8, PS_TYPE_U16, PS_TYPE_U32, PS_TYPE_U64,
+                          PS_TYPE_F32, PS_TYPE_F64, PS_TYPE_C32, PS_TYPE_C64,
+                          PS_TYPE_PTR };
+
+    psLogMsg(__func__,PS_LOG_INFO,"#546 - psImageAlloc shall allocate memory for a psImage structure");
+
+    for (unsigned int t=0;t<types;t++) {
+        psLogMsg(__func__,PS_LOG_INFO,"Testing psImage with type %xh",type[t]);
+
+        for (unsigned int i=0;i<sizes;i++) {
+
+            if (numRows[i] == 0 || numCols[i] == 0) {
+                psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+            }
+
+            image = psImageAlloc(numCols[i],numRows[i],type[t]);
+
+            if (image == NULL) {
+                if (numRows[i] == 0 || numCols[i] == 0) {
+                    continue;
+                }
+                psError(__func__,"psImageAlloc returned NULL for type %x, size %dx%d.",
+                        type[t], numCols[i], numRows[i]);
+                psFree(image);
+                return 1;
+            }
+
+            if (image->type.dimen != PS_DIMEN_IMAGE || image->type.type != type[t]) {
+                psError(__func__,"psImageAlloc allocated wrong dimen/type (%d/%d), should be "
+                        "PS_IMAGE_DIMEN/%d", image->type.dimen, image->type.type, type[t]);
+                psFree(image);
+                return 2;
+            }
+
+            if (image->numCols != numCols[i] || image->numRows != numRows[i]) {
+                psError(__func__,"psImageAlloc allocated wrong size %dx%d, should be %dx%d (type = %d)",
+                        image->numCols, image->numRows, numCols[i], numRows[i],type[t]);
+                psFree(image);
+                return 3;
+            }
+
+            if (image->col0 != 0 || image->row0 != 0) {
+                psError(__func__,"psImageAlloc returned row0/col0 of %d/%d.  Should be 0/0.",
+                        image->row0, image->row0);
+                psFree(image);
+                return 4;
+            }
+
+            if (image->parent != NULL) {
+                psError(__func__,"psImageAlloc returned non-NULL parent");
+                psFree(image);
+                return 5;
+            }
+
+            if (image->children != NULL) {
+                psError(__func__,"psImageAlloc returned non-NULL children array");
+                psFree(image);
+                return 7;
+            }
+
+            switch (type[t]) {
+            case PS_TYPE_U16: {
+                    unsigned int rows = numRows[i];
+                    unsigned int cols = numCols[i];
+
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            image->data.U16[r][c] = 2*c+r;
+                        }
+                    }
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            if (image->data.U16[r][c] != 2*c+r) {
+                                psError(__func__,"Could not set all pixels in uint16 image at (%d,%d)",c,r);
+                                psFree(image);
+                                return 8;
+                            }
+                        }
+                    }
+                }
+                break;
+            case PS_TYPE_F32: {
+                    unsigned int rows = numRows[i];
+                    unsigned int cols = numCols[i];
+
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            image->data.F32[r][c] = 2.0f*c+r;
+                        }
+                    }
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            if (fabsf(image->data.F32[r][c] - (2.0f*c+r)) > FLT_EPSILON) {
+                                psError(__func__,"Could not set all pixels in float image at (%d,%d)",c,r);
+                                psFree(image);
+                                return 8;
+                            }
+                        }
+                    }
+                }
+                break;
+            case PS_TYPE_F64: {
+                    unsigned int rows = numRows[i];
+                    unsigned int cols = numCols[i];
+
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            image->data.F64[r][c] = 2.0f*c+r;
+                        }
+                    }
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            if (fabs(image->data.F64[r][c] - (2.0f*c+r)) > DBL_EPSILON) {
+                                psError(__func__,"Could not set all pixels in double image at (%d,%d)",c,r);
+                                psFree(image);
+                                return 8;
+                            }
+                        }
+                    }
+                }
+                break;
+            case PS_TYPE_C32: {
+                    unsigned int rows = numRows[i];
+                    unsigned int cols = numCols[i];
+
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            image->data.C32[r][c] = r + I * c;
+                        }
+                    }
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            if (fabsf(crealf(image->data.C32[r][c]) - r) > FLT_EPSILON ||
+                                    fabsf(cimagf(image->data.C32[r][c]) - c) > FLT_EPSILON ) {
+                                psError(__func__,"Could not set all pixels in complex image at (%d,%d)",c,r);
+                                psFree(image);
+                                return 8;
+                            }
+                        }
+                    }
+                }
+                break;
+            case PS_TYPE_PTR: {
+                    unsigned int rows = numRows[i];
+                    unsigned int cols = numCols[i];
+                    psImage* temp = psImageAlloc(1,1,PS_TYPE_F32);
+
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            image->data.PTR[r][c] = psMemIncrRefCounter(temp);
+                        }
+                    }
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            if (image->data.PTR[r][c] != temp) {
+                                psError(__func__, "Could not set pixel in pointer image at (%d,%d): %x %x",
+                                        c,r,image->data.PTR[r][c],temp);
+                                psFree(image);
+                                psFree(temp);
+                                return 8;
+                            }
+                        }
+                    }
+                    psFree(temp);
+                }
+                break;
+            default: {
+                    // ignore type and just use as byte bucket.
+                    unsigned int rows = numRows[i];
+                    unsigned int cols = numCols[i]*PSELEMTYPE_SIZEOF(type[t]);
+
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            image->data.U8[r][c] = (uint8_t)(r + c);
+                        }
+                    }
+                    for (int r=0;r<rows;r++) {
+                        for (int c=0;c<cols;c++) {
+                            if (image->data.U8[r][c] != (uint8_t)(r + c)) {
+                                psError(__func__,"Could not set all pixels in image (type=%d) at (%d,%d)",
+                                        type[t],c,r);
+                                psFree(image);
+                                return 8;
+                            }
+                        }
+                    }
+                }
+            }
+            psFree(image);
+        }
+    }
+
+    // #548: Verify no memory leaks or corruption are detected after a valid psImage structure with multiple
+    // children is freed.
+    image = psImageAlloc(100,100,PS_TYPE_F32);
+    psImageSubset(image,50,0,70,20);
+    psImageSubset(image,70,20,90,40);
+
+    psFree(image);
+
+    return 0;
+}
+
+int testImageCopy(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* img3 = NULL;
+    psImage* img4 = NULL;
+    unsigned int c = 128;
+    unsigned int r = 256;
+
+    img = psImageAlloc(c,r,PS_TYPE_F32);
+    for (unsigned row=0;row<r;row++) {
+        psF32* imgRow = img->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            imgRow[col] = (psF32)(row+col);
+        }
+    }
+    img2 = psImageAlloc(c,r,PS_TYPE_F32);
+    for (unsigned row=0;row<r;row++) {
+        psF32* img2Row = img2->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            img2Row[col] = 0.0f;
+        }
+    }
+
+    img3 = psImageCopy(img2,img,PS_TYPE_F32);
+
+    // Verify the returned psImage structure pointer is equal to the input parameter output.
+    if (img2 != img3) {
+        psError(__func__,"the image given for recycled wasn't");
+        return 1;
+    }
+
+    // Verify the returned psImage structure is the same type as the input image structure
+    // if the specified output argument is NULL.
+    img4 = psImageCopy(NULL,img,PS_TYPE_F32);
+    if (img4 == NULL) {
+        psError(__func__,"output image doesn't exist");
+        return 4;
+    }
+    if (img4->type.type != img->type.type) {
+        psError(__func__,"output image is not the same type as input image");
+        return 4;
+    }
+    for (unsigned int row=0;row<r;row++) {
+        psF32* imgInRow = img->data.F32[row];
+        psF32* imgOutRow = img4->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            if( imgInRow[col] != imgOutRow[col] ) {
+                psError(__func__,"Input image not equal to output image at %d,%d!",
+                        col, row);
+                return 4;
+            }
+        }
+    }
+
+    // Verify the returned psImage structure member are equal to the values in
+    // the input psImage structure input.
+
+    #define testImageCopyType(IN,OUT) \
+    img = psImageRecycle(img,c,r,PS_TYPE_##IN); \
+    for (unsigned row=0;row<r;row++) { \
+        ps##IN* imgRow = img->data.IN[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            imgRow[col] = (ps##IN)(row+col); \
+        } \
+    } \
+    img2 = psImageCopy(img2,img,PS_TYPE_##OUT); \
+    if (img2 == NULL) { \
+        psError(__func__,"psImageCopy failed to copy U8."); \
+        return 2; \
+    } \
+    for (unsigned int row=0;row<r;row++) { \
+        ps##IN* imgRow = img->data.IN[row]; \
+        ps##OUT* img2Row = img2->data.OUT[row]; \
+        for (unsigned int col=0;col<c;col++) { \
+            if (abs(imgRow[col] - (ps##IN)(row+col)) > 0.5) { \
+                psError(__func__,"Input image was changed at %d,%d!", \
+                        col,row); \
+                return 2; \
+            } \
+            if (abs(img2Row[col] - (ps##OUT)(imgRow[col])) > 0.5) { \
+                psError(__func__,"returned psImage values after copy don't match at %d,%d " \
+                        "(%d vs %d)",\
+                        col,row,img2Row[col], (ps##OUT)(imgRow[col])); \
+                return 2; \
+            } \
+        } \
+    }
+
+    #define testImageCopyTypes(IN) \
+    printf("to psF32\n"); \
+    testImageCopyType(IN,F32);\
+    printf("to psF64\n"); \
+    testImageCopyType(IN,F64); \
+    printf("to psU8\n"); \
+    testImageCopyType(IN,U8); \
+    printf("to psU16\n"); \
+    testImageCopyType(IN,U16); \
+    printf("to psU32\n"); \
+    testImageCopyType(IN,U32); \
+    printf("to psS8\n"); \
+    testImageCopyType(IN,S8);\
+    printf("to psS16\n"); \
+    testImageCopyType(IN,S16);\
+    printf("to psS32\n"); \
+    testImageCopyType(IN,S32);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Image Copy Test for psU8");
+    testImageCopyTypes(U8);
+    psLogMsg(__func__,PS_LOG_INFO,"Image Copy Test for psU16");
+    testImageCopyTypes(U16);
+    psLogMsg(__func__,PS_LOG_INFO,"Image Copy Test for psU32");
+    testImageCopyTypes(U32);
+    psLogMsg(__func__,PS_LOG_INFO,"Image Copy Test for psS8");
+    testImageCopyTypes(S8);
+    psLogMsg(__func__,PS_LOG_INFO,"Image Copy Test for psS16");
+    testImageCopyTypes(S16);
+    psLogMsg(__func__,PS_LOG_INFO,"Image Copy Test for psS32");
+    testImageCopyTypes(S32);
+    psLogMsg(__func__,PS_LOG_INFO,"Image Copy Test for psF32");
+    testImageCopyTypes(F32);
+    psLogMsg(__func__,PS_LOG_INFO,"Image Copy Test for psF64");
+    testImageCopyTypes(F64);
+
+    // Verify the returned psImage structure pointer is null and program
+    // execution doesn't stop, if the input parameter input is null.
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    img3 = psImageCopy(NULL,NULL,PS_TYPE_F32);
+    if (img3 != NULL) {
+        psError(__func__,"psImageCopy didn't return NULL when input image was NULL.");
+        return 3;
+    }
+
+    psFree(img);
+    psFree(img2);
+    psFree(img3);
+    psFree(img4);
+
+    return 0;
+}
+
Index: /branches/rel3/psLib/test/image/tst_psImageConvolve.c
===================================================================
--- /branches/rel3/psLib/test/image/tst_psImageConvolve.c	(revision 2163)
+++ /branches/rel3/psLib/test/image/tst_psImageConvolve.c	(revision 2163)
@@ -0,0 +1,456 @@
+/** @file  tst_psImageConvolve.c
+ *
+ *  @brief Contains the tests for psImageConvolve.[ch]
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-13 01:22:38 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <math.h>
+#include <float.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "psTest.h"
+#include "pslib.h"
+#include "psType.h"
+
+static int testKernelAlloc(void);
+static int testKernelGenerate(void);
+//static int testImageConvolve(void);
+
+testDescription tests[] = {
+                              {testKernelAlloc,731,"psKernelAlloc",0,false},
+                              {testKernelGenerate,732,"psKernelGenerate",0,false},
+                              //                              {testImageConvolve,733,"psImageConvolve",0,false},
+                              {NULL}
+                          };
+
+int main(int argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    return ! runTestSuite(stderr,"psImage",tests,argc,argv);
+}
+
+static int testKernelAlloc(void)
+{
+    int numCases = 4;
+    int xMin[] = { -5,  0,-10,  5};
+    int xMax[] = {  0,  5, -5, 10};
+    int yMin[] = { -4,  0, -8,  4};
+    int yMax[] = {  0,  4, -4,  8};
+    int i;
+    psKernel* k;
+
+    for (i=0;i<numCases;i++) {
+        k = psKernelAlloc(xMin[i],xMax[i],yMin[i],yMax[i]);
+
+        if (k == NULL) {
+            psError(__func__,"psKernelAlloc returned NULL for [%d:%d,%d:%d].",
+                    xMin[i], xMax[i], yMin[i], yMax[i]);
+            return i*10+1;
+        }
+
+        if (k->xMin != xMin[i] || k->xMax != xMax[i] ||
+                k->yMin != yMin[i] || k->yMax != yMax[i]) {
+            psError(__func__,"Min/max members, [%d:%d,%d:%d], of psKernel wrong. Should be [%d:%d,%d:%d].",
+                    k->xMin,k->xMax, k->yMin, k->yMax,
+                    xMin[i], xMax[i], yMin[i], yMax[i]);
+            return i*10+2;
+        }
+
+        if (k->image->numCols != xMax[i]-xMin[i]+1 ||
+                k->image->numRows != yMax[i]-yMin[i]+1) {
+            psError(__func__,"Size of the kernel image is wrong (%dx%d vs %dx%d).",
+                    xMax[i]-xMin[i]+1, yMax[i]-yMin[i]+1,
+                    k->image->numCols, k->image->numRows);
+            return i*10+2;
+        }
+
+        for (int j=yMin[i]; j<yMax[i]; j++) {
+            if (k->kernel[j]+xMin[i] != k->image->data.PS_TYPE_KERNEL_DATA[j-yMin[i]]) {
+                psError(__func__,"The kernel pointer was set wrong for row %d.",
+                        j);
+                return i*10+4;
+            }
+        }
+
+        psFree(k);
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be a warning (xMin > xMax)");
+    k = psKernelAlloc(5, -5, -2, 2);
+    if (k == NULL) {
+        psError(__func__,"psKernelAlloc returned NULL for xMin > xMax.");
+        return i*10+5;
+    }
+
+    if (k->xMin != -5 || k->xMax != 5) {
+        psError(__func__,"psKernelAlloc didn't swap xMin & xMax.");
+        return i*10+6;
+    }
+
+    psFree(k);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be a warning (yMin > yMax)");
+    k = psKernelAlloc(-2, 2, 5, -5);
+    if (k == NULL) {
+        psError(__func__,"psKernelAlloc returned NULL for yMin > yMax.");
+        return i*10+7;
+    }
+
+    if (k->yMin != -5 || k->yMax != 5) {
+        psError(__func__,"psKernelAlloc didn't swap yMin & yMax.");
+        return i*10+8;
+    }
+
+    psFree(k);
+
+    return 0;
+}
+
+static int testKernelGenerate(void)
+{
+    int size = 4;
+    int t[] = { 1, 2, 8, 10 };
+    int x[] = { 0, 1, 0, -1 };
+    int y[] = { 2, 1, -1, -2 };
+    psKernelType sum;
+
+    psVector* xVec = psVectorAlloc(size,PS_TYPE_U32);
+    psVector* yVec = psVectorAlloc(size,PS_TYPE_U32);
+    psVector* tVec = psVectorAlloc(size,PS_TYPE_U32);
+
+    for (int i = 0; i < size; i++) {
+        xVec->data.U32[i] = x[i];
+        yVec->data.U32[i] = y[i];
+        tVec->data.U32[i] = t[i];
+    }
+
+    psKernel* result = psKernelGenerate(tVec, xVec, yVec, false);
+
+    if (result == NULL) {
+        psError(__func__,"psKernelGenerate returned NULL.");
+        return 1;
+    }
+
+    if (result->xMin != -1 || result->xMax != 1 ||
+            result->yMin != -2 || result->yMax != 2) {
+        psError(__func__,"psKernelGenerate result had a range of [%d:%d,%d:%d].  Suppose to be [0:1,1:2].",
+                result->xMin, result->xMax, result->yMin, result->yMax);
+        return 2;
+    }
+
+    sum = 0.0;
+    for (int y = result->yMin; y <= result->yMax; y++) {
+        for (int x = result->xMin; x <= result->xMax; x++) {
+            sum += result->kernel[y][x];
+        }
+    }
+    if (fabsf(1.0 - sum) > FLT_EPSILON) {
+        psError(__func__,"psKernelGenerate result is not normalized (sum=%g).",
+                sum);
+
+        return 3;
+
+    }
+
+    if (fabsf(result->kernel[2][0] - 1.0/10.0) > FLT_EPSILON ||
+            fabsf(result->kernel[ 1][ 1] - 6.0/10.0) > FLT_EPSILON ||
+            fabsf(result->kernel[ 0][ 0] - 1.0/10.0) > FLT_EPSILON ||
+            fabsf(result->kernel[-1][ 0] - 2.0/10.0) > FLT_EPSILON ||
+            fabsf(result->kernel[-2][-1] - 0.0/10.0) > FLT_EPSILON) {
+        psError(__func__,"psKernelGenerate result values, %g,%g;%g,%g, are wrong. Suppose to be 2,6;1,0.",
+                result->kernel[-1][0], result->kernel[1][1],
+                result->kernel[2][0], result->kernel[-2][-1]);
+
+        return 4;
+    }
+
+    psFree(result);
+    psFree(xVec);
+    psFree(yVec);
+    psFree(tVec);
+
+    xVec = psVectorAlloc(size,PS_TYPE_S16);
+    yVec = psVectorAlloc(size,PS_TYPE_S16);
+    tVec = psVectorAlloc(size,PS_TYPE_S16);
+
+    for (int i = 0; i < size; i++) {
+        xVec->data.S16[i] = x[i];
+        yVec->data.S16[i] = y[i];
+        tVec->data.S16[i] = t[i];
+    }
+
+    result = psKernelGenerate(tVec, xVec, yVec, true);
+
+    if (result == NULL) {
+        psError(__func__,"psKernelGenerate returned NULL.");
+        return 5;
+    }
+
+    if (result->xMin != 0 || result->xMax != 1 ||
+            result->yMin != 0 || result->yMax != 3) {
+        psError(__func__,"psKernelGenerate result had a range of [%d:%d,%d:%d].  Suppose to be [0:1,1:2].",
+                result->xMin, result->xMax, result->yMin, result->yMax);
+        return 6;
+    }
+
+    sum = 0.0;
+    for (int y = result->yMin; y <= result->yMax; y++) {
+        for (int x = result->xMin; x <= result->xMax; x++) {
+            sum += result->kernel[y][x];
+        }
+    }
+    if (fabsf(1.0 - sum) > FLT_EPSILON) {
+        psError(__func__,"psKernelGenerate result is not normalized (sum=%g).",
+                sum);
+
+        return 7;
+
+    }
+
+    if (fabsf(result->kernel[0][0] - 1.0/21.0) > FLT_EPSILON ||
+            fabsf(result->kernel[2][0] - 2.0/21.0) > FLT_EPSILON ||
+            fabsf(result->kernel[3][1] - 8.0/21.0) > FLT_EPSILON ||
+            fabsf(result->kernel[2][1] - 10.0/21.0) > FLT_EPSILON) {
+        psError(__func__,"psKernelGenerate result values, %g,%g;%g,%g, are wrong. Suppose to be 2,6;1,0.",
+                result->kernel[1][0], result->kernel[1][1],
+                result->kernel[2][0], result->kernel[2][1]);
+
+        return 8;
+    }
+
+    psFree(result);
+    psFree(xVec);
+    psFree(yVec);
+    psFree(tVec);
+
+    xVec = psVectorAlloc(size,PS_TYPE_F32);
+    yVec = psVectorAlloc(size,PS_TYPE_F32);
+    tVec = psVectorAlloc(size,PS_TYPE_F32);
+
+    for (int i = 0; i < size; i++) {
+        xVec->data.F32[i] = x[i]+0.1;
+        yVec->data.F32[i] = y[i]+0.2;
+        tVec->data.F32[i] = t[i]+0.3;
+    }
+
+    tVec->n--; // decrease size by one to make vectors unequal in length.
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be a warning - not automatically tested.");
+    result = psKernelGenerate(tVec, xVec, yVec, false);
+    if (result == NULL) {
+        psError(__func__,"psKernelGenerate returned NULL.");
+        return 9;
+    }
+
+    // make sure last sample is not used
+    if (fabsf(result->kernel[2][0] - 1.0/8.0) > FLT_EPSILON ||
+            fabsf(result->kernel[ 1][ 1] - 6.0/8.0) > FLT_EPSILON ||
+            fabsf(result->kernel[ 0][ 0] - 1.0/8.0) > FLT_EPSILON) {
+        psError(__func__,"psKernelGenerate result values wrong for truncated time vector.");
+
+        return 10;
+    }
+
+    psFree(result);
+
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be a error (time vector NULL).");
+    result = psKernelGenerate(NULL, xVec, yVec, true);
+    if (result != NULL) {
+        psError(__func__,"psKernelGenerate returned a kernel with no time vector.");
+        return 11;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be a error (x vector NULL).");
+    result = psKernelGenerate(tVec, NULL, yVec, true);
+    if (result != NULL) {
+        psError(__func__,"psKernelGenerate returned a kernel with no x vector.");
+        return 11;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be a error (y vector NULL).");
+    result = psKernelGenerate(tVec, xVec, NULL, true);
+    if (result != NULL) {
+        psError(__func__,"psKernelGenerate returned a kernel with no y vector.");
+        return 11;
+    }
+
+    psFree(xVec);
+    psFree(yVec);
+    psFree(tVec);
+    psFree(result);
+
+    return 0;
+}
+
+/*
+static int testImageConvolve(void)
+{
+    const int r = 200;
+    const int c = 300;
+    int sum;
+ 
+    // approximate a normalized gaussian kernel.
+    psKernel* g = psKernelAlloc(-1,1,-1,1);
+    g->kernel[-1][-1] =
+        g->kernel[-1][1] =
+            g->kernel[1][-1] =
+                g->kernel[1][1] = 0.0113;
+    g->kernel[1][0] =
+        g->kernel[-1][0] =
+            g->kernel[0][-1] =
+                g->kernel[0][1] = 0.0838;
+    g->kernel[0][0] = 0.6193;
+ 
+    // create a normalized non-symetric kernel.
+    psKernel* nsk = psKernelAlloc(0,2,0,2);
+    sum = 0.0;
+    for (int i=0;i<2;i++) {
+        for (int j=0;j<2;j++) {
+            nsk->kernel[i][j] = i+j;
+            sum = i+j;
+        }
+    }
+    for (int i=0;i<2;i++) {
+        for (int j=0;j<2;j++) {
+            nsk->kernel[i][j] /= sum;
+        }
+    }
+ 
+ 
+    psImage* img = psImageAlloc(c,r,PS_TYPE_F32);
+    memset(img->data.F32[0],0,c*r*PSELEMTYPE_SIZEOF(PS_TYPE_F32));
+    img->data.F32[0][0] = 1.0f;
+    img->data.F32[r/2][c/2] = 1.0f;
+    img->data.F32[r-1][c/2] = 1.0f;
+ 
+    // test spacial convolution of gaussian
+    psLogMsg(__func__,PS_LOG_INFO,"Testing direct gaussian convolution");
+    psImage* out = psImageConvolve(NULL, img, g, true);
+ 
+    if (out == NULL) {
+        psError(__func__, "psImageConvolve returned a NULL for direct gaussian case.");
+        return 1;
+    }
+ 
+    if (out->numCols != c || out->numRows != r) {
+        psError(__func__, "psImageConvolve result image is %dx%d, but expected %dx%d.",
+                out->numCols, out->numRows,
+                c,r);
+        return 2;
+    }
+ 
+    if (out->type.type != PS_TYPE_F32) {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,out->type.type);
+        psError(__func__, "psImageConvolve result image is of type %s, not psF32.",
+                typeStr);
+        return 3;
+    }
+ 
+    // test values
+    for (int i=-1;i<1;i++) {
+        for (int j=-1;j<1;j++) {
+            if (fabsf(out->data.F32[r/2+i][c/2+j] - g->kernel[i][j]) > 0.0001) {
+                psError(__func__,"Convolved image wrong at %d,%d.  Value is %g, expected %g.",
+                        c/2+j,r/2+i,
+                        out->data.F32[r/2+i][c/2+j], g->kernel[i][j]);
+                return 4;
+            }
+            if (i >= 0 && j >= 0 && fabsf(out->data.F32[i][j] - g->kernel[i][j]) > 0.0001) {
+                psError(__func__,"Convolved image wrong at %d,%d.  Value is %g, expected %g.",
+                        j,i,
+                        out->data.F32[i][j], g->kernel[i][j]);
+                return 5;
+            }
+            if (i <= 0 && fabsf(out->data.F32[r-1+i][c/2+j] - g->kernel[i][j]) > 0.0001) {
+                psError(__func__,"Convolved image wrong at %d,%d.  Value is %g, expected %g.",
+                        c/2+j,r-1+i,
+                        out->data.F32[r-1+i][c/2+j], g->kernel[i][j]);
+                return 6;
+            }
+        }
+    }
+ 
+    // test fourier convolution of gaussian
+    psLogMsg(__func__,PS_LOG_INFO,"Testing fourier gaussian convolution");
+    psKernel* gg = psKernelAlloc(1,3,1,3);
+    gg->kernel[1][1] =
+        gg->kernel[1][3] =
+            gg->kernel[3][1] =
+                gg->kernel[3][3] = 0.0113;
+    gg->kernel[3][2] =
+        gg->kernel[1][2] =
+            gg->kernel[2][1] =
+                gg->kernel[2][3] = 0.0838;
+    gg->kernel[2][2] = 0.6193;
+    img->data.F32[0][0] = 0.0f;
+    img->data.F32[r/2][c/2] = 1.0f;
+    img->data.F32[r-1][c/2] = 0.0f;
+    psImage* out2 = psImageConvolve(out, img, gg, false);
+ 
+    if (out == NULL) {
+        psError(__func__, "psImageConvolve returned a NULL for gaussian case.");
+        return 10;
+    }
+ 
+    if (out != out2) {
+        psError(__func__, "psImageConvolve didn't recycle the supplied out image struct.");
+        return 11;
+    }
+ 
+    if (out->numCols != c || out->numRows != r) {
+        psError(__func__, "psImageConvolve result image is %dx%d, but expected %dx%d.",
+                out->numCols, out->numRows,
+                c,r);
+        return 12;
+    }
+ 
+    if (out->type.type != PS_TYPE_F32) {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,out->type.type);
+        psError(__func__, "psImageConvolve result image is of type %s, not psF32.",
+                typeStr);
+        return 13;
+    }
+ 
+    psImageWriteSection(out2,0,0,0,NULL,0,"out2.fits");
+    // test values
+    for (int i=-1;i<1;i++) {
+        for (int j=-1;j<1;j++) {
+            if (fabsf(out->data.F32[r/2+i][c/2+j] - g->kernel[i][j]) > 0.0001) {
+                psError(__func__,"Convolved image wrong at %d,%d.  Value is %g, expected %g.",
+                        c/2+j,r/2+i,
+                        out->data.F32[r/2+i][c/2+j], g->kernel[i][j]);
+                psImageWriteSection(out,0,0,0,NULL,0,"problem.fits");
+                return 14;
+            }
+            if (i >= 0 && j >= 0 && fabsf(out->data.F32[i][j] - g->kernel[i][j]) > 0.0001) {
+                psError(__func__,"Convolved image wrong at %d,%d.  Value is %g, expected %g.",
+                        j,i,
+                        out->data.F32[i][j], g->kernel[i][j]);
+                return 15;
+            }
+            if (i <= 0 && fabsf(out->data.F32[r-1+i][c/2+j] - g->kernel[i][j]) > 0.0001) {
+                psError(__func__,"Convolved image wrong at %d,%d.  Value is %g, expected %g.",
+                        c/2+j,r-1+i,
+                        out->data.F32[r-1+i][c/2+j], g->kernel[i][j]);
+                return 16;
+            }
+        }
+    }
+ 
+    psFree(g);
+    psFree(img);
+    psFree(nsk);
+    psFree(out);
+    return 0;
+}
+*/
+
Index: /branches/rel3/psLib/test/image/tst_psImageExtraction.c
===================================================================
--- /branches/rel3/psLib/test/image/tst_psImageExtraction.c	(revision 2163)
+++ /branches/rel3/psLib/test/image/tst_psImageExtraction.c	(revision 2163)
@@ -0,0 +1,1434 @@
+/** @file  tst_psImageExtraction.c
+*
+*  @brief Contains the tests for psImageExtraction.[ch]
+*
+*
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-10-15 20:00:56 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+#include<stdlib.h>
+#include<string.h>
+
+#include "psTest.h"
+#include "pslib.h"
+#include "psType.h"
+
+static int testImageSlice(void);
+static int testImageSubset(void);
+static int testImageSubsection(void);
+static int testImageTrim(void);
+static int testImageCut(void);
+static int testImageRadialCut(void);
+
+
+testDescription tests[] = {
+                              {testImageSubset,547,"psImageSubset",0,false},
+                              {testImageSubset,550,"psImageSubset",0,true},
+                              {testImageSubsection,730,"psImageSubsection",0,false},
+                              {testImageSlice, 552, "psImageSlice", 0, false},
+                              {testImageTrim, 744, "psImageTrim", 0, false},
+                              {testImageCut, 555, "psImageCut", 0, false},
+                              {testImageRadialCut, 557, "psImageRadialCut", 0, false},
+                              {NULL}
+                          };
+
+int main( int argc, char* argv[] )
+{
+    return ! runTestSuite( stderr, "psImage", tests, argc, argv );
+}
+
+int testImageSlice(void)
+{
+    const int r = 200;
+    const int c = 300;
+    const int m = r / 2 -1;
+    const int n = r / 4 -1;
+    psVector* out = NULL;
+    psImage* image;
+    psVector* positions = psVectorAlloc( r, PS_TYPE_U32 );
+    psImage* mask = psImageAlloc( c, r, PS_TYPE_MASK );
+    psStats* stat = psStatsAlloc( PS_STAT_SAMPLE_MEDIAN );
+
+    /*
+        This function shall extract pixels from a specified region of a psImage
+        structure into a vector using a specified statistical method.
+
+        Verify the returned psVector structure contains expected data, if the 
+        input psImage input has known data and the psStats structure specifies 
+        a known statistical method. At least two different statistical methods 
+        should be used within a valid range of psImage data. Allow for a delta 
+        when comparing results to allow for testing a different platforms. Two 
+        cases should be used for each possible direction. Data region cases 
+        should include 0x0, 1x1, Nx1, 1xN, NxN, MxN
+     
+     */
+
+    for ( int row = 0;row < r;row++ ) {
+        psMaskType* maskRow = mask->data.PS_TYPE_MASK_DATA[row];
+        for ( int col = 0;col < c;col++ ) {
+            maskRow[ col ] = 0;
+        }
+    }
+
+    #define PSIMAGESLICE_TEST1(TYPE,M,N,DIRECTION,TRUTH_SIZE,TRUTHPIX_X,TRUTHPIX_Y,TESTNUM) \
+    image = psImageAlloc( c, r, PS_TYPE_##TYPE ); \
+    for ( int row = 0;row < r;row++ ) { \
+        ps##TYPE *imageRow = image->data.TYPE[ row ]; \
+        ps##TYPE rowOffset = row * 2; \
+        for ( int col = 0;col < c;col++ ) { \
+            imageRow[ col ] = col + rowOffset; \
+        } \
+    } \
+    out = psImageSlice(out,positions,image,mask,1,c/10,r/10,c/10+M,r/10+N,DIRECTION,stat); \
+    \
+    if (out->n != TRUTH_SIZE) { \
+        psError(__func__,"Number of results is wrong (%d, not %d)", \
+                out->n,n); \
+        return TESTNUM*4+1; \
+    } \
+    \
+    if (positions->n != TRUTH_SIZE) { \
+        psError(__func__,"Number of results for positions vector is wrong (%d, not %d)", \
+                out->n,n); \
+        return TESTNUM*4+2; \
+    } \
+    \
+    for (int i=0;i<out->n;i++) { \
+        if (fabs(out->data.F64[i]-image->data.TYPE[r/10+TRUTHPIX_Y][c/10+TRUTHPIX_X]) > 1.0/(psF64)r) { \
+            psError(__func__,"Improper result at position %d.  Got %g, expected %g",i, \
+                    out->data.F64[i],image->data.TYPE[r/10+TRUTHPIX_Y][c/10+TRUTHPIX_X]); \
+            return TESTNUM*4+3; \
+        } \
+        if (DIRECTION == PS_CUT_X_POS || DIRECTION == PS_CUT_X_NEG) { \
+            if (positions->data.U32[i] != c/10+TRUTHPIX_X) { \
+                psError(__func__,"Improper positions (%d vs %d) result @ %d.", \
+                        positions->data.U32[i],c/10+TRUTHPIX_X,i); \
+                return TESTNUM*4+4; \
+            } \
+        } else { \
+            if (positions->data.U32[i] != r/10+TRUTHPIX_Y) { \
+                psError(__func__,"Improper positions (%d vs %d) result @ %d.", \
+                        positions->data.U32[i],r/10+TRUTHPIX_Y,i); \
+                return TESTNUM*4+4; \
+            } \
+        } \
+    } \
+    psFree(image);
+
+    #define PSIMAGESLICE_TEST(TYPE) \
+    /* test MxN case */ \
+    PSIMAGESLICE_TEST1(TYPE, m, n, PS_CUT_X_POS, m, i, n / 2, 0 ); \
+    PSIMAGESLICE_TEST1(TYPE, m, n, PS_CUT_X_NEG, m, m - 1 - i, n / 2, 1 ); \
+    PSIMAGESLICE_TEST1(TYPE, m, n, PS_CUT_Y_POS, n, m / 2, i, 2 ); \
+    PSIMAGESLICE_TEST1(TYPE, m, n, PS_CUT_Y_NEG, n, m / 2, n - 1 - i, 3 ); \
+    \
+    /* test Mx1 case */ \
+    PSIMAGESLICE_TEST1(TYPE, m, 1, PS_CUT_X_POS, m, i, 0, 4 ); \
+    PSIMAGESLICE_TEST1(TYPE, m, 1, PS_CUT_X_NEG, m, m - 1 - i, 0, 5 ); \
+    PSIMAGESLICE_TEST1(TYPE, m, 1, PS_CUT_Y_POS, 1, m / 2, 0, 6 ); \
+    PSIMAGESLICE_TEST1(TYPE, m, 1, PS_CUT_Y_NEG, 1, m / 2, 0, 7 ); \
+    \
+    /* test 1xN case */ \
+    PSIMAGESLICE_TEST1(TYPE, 1, n, PS_CUT_X_POS, 1, 0, n / 2, 8 ); \
+    PSIMAGESLICE_TEST1(TYPE, 1, n, PS_CUT_X_NEG, 1, 0, n / 2, 9 ); \
+    PSIMAGESLICE_TEST1(TYPE, 1, n, PS_CUT_Y_POS, n, 0, i, 10 ); \
+    PSIMAGESLICE_TEST1(TYPE, 1, n, PS_CUT_Y_NEG, n, 0, n - 1 - i, 11 ); \
+    \
+    /* test 1x1 case */ \
+    PSIMAGESLICE_TEST1(TYPE, 1, 1, PS_CUT_X_POS, 1, 0, 0, 12 ); \
+    PSIMAGESLICE_TEST1(TYPE, 1, 1, PS_CUT_X_NEG, 1, 0, 0, 13 ); \
+    PSIMAGESLICE_TEST1(TYPE, 1, 1, PS_CUT_Y_POS, 1, 0, 0, 14 ); \
+    PSIMAGESLICE_TEST1(TYPE, 1, 1, PS_CUT_Y_NEG, 1, 0, 0, 15 ); \
+
+    PSIMAGESLICE_TEST(F32);
+    PSIMAGESLICE_TEST(F64);
+    PSIMAGESLICE_TEST(U16);
+
+    image = psImageAlloc( c, r, PS_TYPE_F32 );
+
+    /*
+       Verify the returned psVector structure pointer is null and program 
+       execution doesn't stop, if input psImage input is null.
+
+    */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    out = psImageSlice( out,
+                        NULL, NULL,
+                        NULL, 0,
+                        c/10, r/10,
+                        c/10 + 1, r/10 + 1,
+                        PS_CUT_X_POS,
+                        stat );
+    if ( out != NULL ) {
+        psError( __func__, "Giving a NULL image, psImageSlice didn't return NULL as expected" );
+        return 101;
+    }
+
+
+    /*
+       Verify the returned psVector structure pointer is null and program 
+       execution doesn't stop, if input psStats stats is null.
+    */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    out = psImageSlice( out,
+                        NULL, image,
+                        mask, 1,
+                        c/10, r/10,
+                        c/10 + 1,
+                        r/10 + 1,
+                        PS_CUT_X_POS,
+                        NULL );
+    if ( out != NULL ) {
+        psError( __func__, "Giving a NULL stat struct, psImageSlice didn't return NULL as expected" );
+        return 102;
+    }
+    /*
+
+       Verify the returned psVector structure pointer is null and program 
+       executions doesn't stop, if the input direction is not set to one of 
+       the two valid values.
+    */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    out = psImageSlice( out, NULL,
+                        image,
+                        mask, 1,
+                        c/10, r/10,
+                        c/10+1, r/10+1,
+                        5,
+                        stat);
+    if ( out != NULL ) {
+        psError( __func__, "Giving a bogus direction flag, psImageSlice didn't return NULL as expected" );
+        return 103;
+    }
+
+    /*
+       Verify the returned psVector structure pointer is null and program 
+       execution doesn't stop, if the input nrow and/or ncol are zero.
+    */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    out = psImageSlice( out,
+                        NULL,
+                        image,
+                        mask, 1,
+                        c/10, r/10,
+                        c/10, r/10,
+                        PS_CUT_X_POS,
+                        stat );
+    if ( out != NULL ) {
+        psError( __func__, "Giving a 0x0 region, psImageSlice didn't return NULL as expected" );
+        return 104;
+    }
+
+    /*
+       Verify the returned psVector structure pointer is null and program 
+       execution doesn't stop, if the inputs row, col, nrow, ncol specify a 
+       regions of data that is not within the input psImage structure.
+    */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    out = psImageSlice( out, NULL,
+                        image,
+                        mask, 1,
+                        c+1, r/10,
+                        c+2, r/10+10,
+                        PS_CUT_X_POS,
+                        stat );
+    if ( out != NULL ) {
+        psError( __func__, "Giving an invalid x position, psImageSlice didn't return NULL as expected" );
+        return 105;
+    }
+
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    out = psImageSlice( out, NULL,
+                        image,
+                        mask, 1,
+                        c/10, r+1,
+                        c/10+1,r+5,
+                        PS_CUT_X_POS,
+                        stat );
+    if ( out != NULL ) {
+        psError( __func__, "Giving an invalid y position, psImageSlice didn't return NULL as expected" );
+        return 106;
+    }
+
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    out = psImageSlice( out, NULL,
+                        image,
+                        mask, 1,
+                        c/10, r/10,
+                        c+1, r/10+1,
+                        PS_CUT_X_POS,
+                        stat);
+    if ( out != NULL ) {
+        psError( __func__, "Giving an invalid numCols, psImageSlice didn't return NULL as expected" );
+        return 107;
+    }
+
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    out = psImageSlice( out, NULL,
+                        image,
+                        mask, 1,
+                        c/10, r/10,
+                        c/10+1, r + 1,
+                        PS_CUT_X_POS,
+                        stat);
+    if ( out != NULL ) {
+        psError( __func__, "Giving an invalid numRows, psImageSlice didn't return NULL as expected" );
+        return 108;
+    }
+
+    /*
+       Verify the returned psVector structure pointer is null and program 
+       execution doesn't stop, if the input psStat structure member options is 
+       zero which indicates no statistic method specified.
+    */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error." );
+    stat->options = 0;
+    out = psImageSlice( out, NULL,
+                        image,
+                        mask, 1,
+                        c/10, r/10,
+                        c/10+1, r/10+1,
+                        PS_CUT_X_POS,
+                        stat);
+    if ( out != NULL ) {
+        psError( __func__, "Giving an invalid numRows, psImageSlice didn't return NULL as expected" );
+        return 109;
+    }
+
+    /* Verify that a mask of different size than the input image returns null and program
+       execution doesn't stop.
+    */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error mask size != image size.");
+    stat->options = PS_STAT_SAMPLE_MEDIAN;
+    psImage* maskSz = psImageAlloc( r, c, PS_TYPE_MASK );
+    out = psImageSlice( out, NULL,
+                        image,
+                        maskSz, 1,
+                        c/10, r/10,
+                        c/10+1, r/10+1,
+                        PS_CUT_X_POS,
+                        stat);
+    if ( out != NULL ) {
+        psError( __func__, "Mask size different than image size didn't return NULL as expected" );
+        return 110;
+    }
+
+    /* Verify the a invalid type mask returns null and program execution doesn't stop.
+    */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error invalid mask type.");
+    psImage* maskS8 = psImageAlloc( c, r, PS_TYPE_S8 );
+    out =  psImageSlice( out, NULL,
+                         image,
+                         maskS8, 1,
+                         c/10, r/10,
+                         c/10+1, r/10+1,
+                         PS_CUT_X_POS,
+                         stat);
+    if ( out != NULL ) {
+        psError( __func__, "Mask invalid type didn't return NULL as expected.");
+        return 111;
+    }
+
+    /* Verify the input image is an invalid type */
+    psLogMsg( __func__, PS_LOG_INFO, "Following should be an error invalid image type.");
+    psImage* imgU8 = psImageAlloc( c, r, PS_TYPE_U8 );
+    out = psImageSlice( out, NULL,
+                        imgU8,
+                        mask, 1,
+                        c/10, r/10,
+                        c/10+1, r/10+1,
+                        PS_CUT_X_POS,
+                        stat);
+    if ( out != NULL ) {
+        psError( __func__, "Input image with invalid type didn't return NULL as expected.");
+        return 112;
+    }
+
+    psFree( image );
+    psFree( positions );
+    psFree( mask );
+    psFree( out );
+    psFree( stat );
+    psFree( imgU8 );
+    psFree( maskS8 );
+    psFree( maskSz );
+
+    return 0;
+
+}
+
+// #547: psImageSubset shall create child image of a specified size from a parent psImage structure
+int testImageSubset(void)
+{
+    psImage preSubsetStruct;
+    psImage* original;
+    psImage* subset1 = NULL;
+    psImage* subset2 = NULL;
+    psImage* subset3 = NULL;
+    int c = 128;
+    int r = 256;
+
+    original = psImageAlloc(c,r,PS_TYPE_U32);
+    for (int row=0;row<r;row++) {
+        for (int col=0;col<c;col++) {
+            original->data.F32[row][col] = row*1000+col;
+        }
+    }
+
+    memcpy(&preSubsetStruct,original,sizeof(psImage));
+
+    subset2 = psImageSubset(original,c/4,r/4,c/4+c/2,r/4+r/2);
+
+    subset3 = psImageSubset(original,0,0,c/2,r/2);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure members nrow and ncol are equal to "
+             "the input parameter nrow and ncol respectively.");
+
+    if (subset2->numCols != c/2 || subset2->numRows != r/2) {
+        psError(__func__,"psImageSubset output size was not proper(%dx%d, should be %dx%d).",
+                subset2->numCols, subset2->numRows, c/2,r/2);
+        return 1;
+    }
+
+    if (subset3->numCols != c/2 || subset3->numRows != r/2) {
+        psError(__func__,"psImageSubset output size was not proper(%dx%d, should be %dx%d).",
+                subset3->numCols, subset3->numRows, c/2,r/2);
+        return 2;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure contains expected values in the "
+             "row member, if the input psImage structure image contains known values.");
+
+    for (int row=0;row<r/2;row++) {
+        for (int col=0;col<c/2;col++) {
+            if (subset2->data.U32[row][col] != original->data.U32[row+r/4][col+c/4]) {
+                psError(__func__,"psImageSubset output #1 was wrong at %dx%d (%d vs %d).",
+                        row,col,subset2->data.U32[row][col], original->data.U32[row+r/4][col+c/4]);
+                return 3;
+            }
+            if (subset3->data.U32[row][col] != original->data.U32[row][col]) {
+                psError(__func__,"psImageSubset output #1 was wrong at %dx%d (%d vs %d).",
+                        row,col,subset2->data.U32[row][col], original->data.U32[row][col]);
+                return 4;
+            }
+        }
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure member type is equal to the input "
+             "psImage structure member type.");
+
+    if (subset2->type.type != PS_TYPE_U32) {
+        psError(__func__,"psImageSubset output type was not proper(%d, should be %d).",
+                subset2->type.type, PS_TYPE_U32);
+        return 6;
+    }
+    if (subset3->type.type != PS_TYPE_U32) {
+        psError(__func__,"psImageSubset output type was not proper(%d, should be %d).",
+                subset3->type.type, PS_TYPE_U32);
+        return 7;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure members row0 and col0 are equal to "
+             "the input parameters row0 and col0 respectively.");
+
+    if (subset2->col0 != c/4 || subset2->row0 != r/4) {
+        psError(__func__,"psImageSubset didn't set col0/row0 for subset2 (%d/%d, should be %d/%d).",
+                subset2->col0,subset2->row0,c/4,r/4);
+        return 8;
+    }
+    if (subset3->col0 != 0 || subset3->row0 != 0) {
+        psError(__func__,"psImageSubset didn't set col0/row0 for subset3 (%d/%d, should be %d/%d).",
+                subset3->col0,subset3->row0,0,0);
+        return 9;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure member parent is equal to the "
+             "input psImage structure pointer image.");
+
+    if (subset2->parent != original || subset3->parent != original) {
+        psError(__func__,"psImageSubset didn't set parent.");
+        return 10;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure member children is null.");
+
+    if (subset2->children != NULL || subset3->children != NULL) {
+        psError(__func__,"psImageSubset didn't set children to NULL.");
+        return 11;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the input psImage structure image only has the following members "
+             "changed: 1) Nchildren is increased by one. 2) parent contains pointer psImage structure "
+             "out at parent[Nchildren-1].");
+
+    if (original->children == NULL || original->children->n != 2) {
+        psError(__func__,"psImageSubset didn't increment number of children by one per subset.");
+        return 12;
+    }
+    if (original->children->data[0] != subset2 || original->children->data[1] != subset3) {
+        psError(__func__,"psImageSubset didn't properly store the children pointers.");
+        return 13;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure pointer is null and program "
+             "execution doesn't stop, if the input parameter image is null. Also verified the input "
+             "psImage structure is not modified.");
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(NULL,0,0,c/2,r/2);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when input image was NULL.");
+        return 14;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure pointer is null and program "
+             " execution doesn't stop, if the input parameters nrow and/or ncol are zero. Also verify "
+             "input psImage structure is not modified.");
+
+    memcpy(&preSubsetStruct,original,sizeof(psImage));
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,0,r/2,c/2,r/2);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when numRows=0.");
+        return 15;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,c/2,0,c/2,r/2);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when numCols=0.");
+        return 16;
+    }
+    if (memcmp(original,&preSubsetStruct,sizeof(psImage)) != 0) {
+        psError(__func__,"psImageSubset changed the original struct though it failed to subset.");
+        return 17;
+    }
+
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure pointer is null and program "
+             "execution doesn't stop, if the input parameters row0 and col0 are not within the range of "
+             "values of psImage structure image.");
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,0,0,c/2,r*2);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when subset origin was outside of "
+                "image (via cols).");
+        return 18;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,0,0,c*2,r/2);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when subset origin was outside of "
+                "image (via rows).");
+        return 19;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,-1,0,c/2,r/2);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when subset origin was outside of "
+                "image (col0=-1).");
+        return 20;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,0,-1,c/2,r/2);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when subset origin was outside of "
+                "image (row0=-1).");
+        return 21;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Verify the returned psImage structure pointer is null and program "
+             "execution doesn't stop if the input parameters nrow, ncol, row0 and col0 specify a range of "
+             "data not within the input psImage structure image.  Also verify the input psImage structure "
+             "is not modified.");
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,0,0,c/2,r+1);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when subset was outside of image (via rows).");
+        return 22;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,0,0,c+1,r/2);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when subset was outside of image (via cols).");
+        return 23;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow...");
+    subset1 = psImageSubset(original,0,0,c+1,r+1);
+    if (subset1 != NULL) {
+        psError(__func__,"psImageSubset didn't return NULL when subset was outside of image (via row+cols).");
+        return 24;
+    }
+
+    psLogMsg(__func__, PS_LOG_INFO, "psImageFreeChildren shall deallocate any children images of a "
+             "psImage structure");
+
+    memcpy(&preSubsetStruct,original,sizeof(psImage));
+
+    psImageFreeChildren(original);
+
+    // Verify the returned psImage structure member Nchildren is set to zero.
+    if (original->children != NULL && original->children->n > 0) {
+        psError(__func__,"psImageFreeChildren didn't set number of children to zero.");
+        return 25;
+    }
+
+    //Verify the returned psImage structure members type, nrow, ncol, row0, col0, rows and parent are not
+    // modified.
+    if (preSubsetStruct.numRows != original->numRows ||
+            preSubsetStruct.numCols != original->numCols ||
+            preSubsetStruct.row0 != original->row0 ||
+            preSubsetStruct.col0 != original->col0) {
+
+        psError(__func__,"psImageFreeChildren modified parent's non-children elements.");
+        return 27;
+    }
+
+    psFree(original);
+
+    return 0;
+}
+
+// #730: psImageSubsection shall create child image of a specified size from a parent psImage structure
+int testImageSubsection(void)
+{
+    psImage* original;
+    psImage* subset;
+    int c = 128;
+    int r = 256;
+    int i;
+    int numRegions = 4;
+    int x1[] = {  0, 32, 64, 32};
+    int x2[] = { 32, 64,127, 64};
+    int y1[] = {  0, 32, 32,128};
+    int y2[] = { 32, 64, 64,255};
+
+    original = psImageAlloc(c,r,PS_TYPE_U32);
+    for (int row=0;row<r;row++) {
+        for (int col=0;col<c;col++) {
+            original->data.F32[row][col] = row*1000+col;
+        }
+    }
+
+    for (i=0; i<numRegions; i++) {
+        char sectionStr[64];
+        sprintf(sectionStr,"[%d:%d,%d:%d]",x1[i],x2[i],y1[i],y2[i]);
+
+        psLogMsg(__func__,PS_LOG_INFO,"Testing subsection %s.",
+                 sectionStr);
+
+        subset = psImageSubsection(original,sectionStr);
+
+        if (subset == NULL) {
+            psError(__func__,"psImageSubsection returned a NULL with a subset of %s.",
+                    sectionStr);
+            return 10*i+1;
+        }
+
+        if (subset->type.type != PS_TYPE_U32) {
+            psError(__func__,"psImageSubsection output type was not proper(%d, should be %d).",
+                    subset->type.type, PS_TYPE_U32);
+            return 10*i+2;
+        }
+
+        if (subset->col0 != x1[i] || subset->row0 != y1[i]) {
+            psError(__func__,"psImageSubsection didn't set properly col0/row0 (%d/%d, should be %d/%d).",
+                    subset->col0,subset->row0,x1[i],y1[i]);
+            return 10*i+3;
+        }
+
+        if (subset->parent != original) {
+            psError(__func__,"psImageSubsection didn't set parent.");
+            return 10*i+4;
+        }
+
+        if (subset->children != NULL) {
+            psError(__func__,"psImageSubsection didn't set children to NULL.");
+            return 10*i+5;
+        }
+
+        if (original->children == NULL || original->children->n != i+1) {
+            psError(__func__,"psImageSubsection didn't increment number of children by one per subset.");
+            return 10*i+6;
+        }
+
+
+        if (original->children->data[i] != subset) {
+            psError(__func__,"psImageSubsection didn't properly store the children pointer.");
+            return 10*i+7;
+        }
+
+        int numCols = x2[i]-x1[i]+1;
+        int numRows = y2[i]-y1[i]+1;
+        if (subset->numCols != numCols || subset->numRows != numRows) {
+            psError(__func__,"psImageSubsection output size was not proper(%dx%d, should be %dx%d).",
+                    subset->numCols, subset->numRows, numCols, numRows);
+            return 10*i+8;
+        }
+
+        for (int row=0;row<numRows;row++) {
+            for (int col=0;col<numCols;col++) {
+                if (subset->data.U32[row][col] != original->data.U32[row+y1[i]][col+x1[i]]) {
+                    psError(__func__,"psImageSubset output #1 was wrong at %dx%d (%d vs %d).",
+                            row,col,subset->data.U32[row][col], original->data.U32[row+y1[i]][col+x1[i]]);
+                    return 10*i+9;
+                }
+            }
+        }
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (x1>x2)");
+    subset = psImageSubsection(original,"[64:32,32:64]");
+    if (subset != NULL) {
+        psError(__func__,"psImageSubsection didn't return NULL when x1 > x2.");
+        return 10*i+10;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (y1>y2)");
+    subset = psImageSubsection(original,"[32:64,64:32]");
+    if (subset != NULL) {
+        psError(__func__,"psImageSubsection didn't return NULL when y1 > y2.");
+        return 10*i+11;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (x2>nCols)");
+    subset = psImageSubsection(original,"[64:256,32:64]"); // assumes c<256
+    if (subset != NULL) {
+        psError(__func__,"psImageSubsection didn't return NULL when x2 > c.");
+        return 10*i+12;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (y2>=nRows)");
+    subset = psImageSubsection(original,"[32:64,64:256]"); // assumes r==256
+    if (subset != NULL) {
+        psError(__func__,"psImageSubsection didn't return NULL when y2 > r.");
+        return 10*i+13;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (malformed string - no brackets)");
+    subset = psImageSubsection(original,"32:64,32:64");
+    if (subset != NULL) {
+        psError(__func__,"psImageSubsection didn't return NULL when subsection was '32:64,32:64'.");
+        return 10*i+14;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (malformed string - no colons)");
+    subset = psImageSubsection(original,"[32-64,32-64]");
+    if (subset != NULL) {
+        psError(__func__,"psImageSubsection didn't return NULL when subsection was '[32-64,32-64]'.");
+        return 10*i+15;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (malformed string - not four numbers)");
+    subset = psImageSubsection(original,"[32:64,32]");
+    if (subset != NULL) {
+        psError(__func__,"psImageSubsection didn't return NULL when subsection was '[32:64,32]'.");
+        return 10*i+16;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (image is NULL)");
+    subset = psImageSubsection(NULL,"[32:64,32:64]");
+    if (subset != NULL) {
+        psError(__func__,"psImageSubsection didn't return NULL when image was NULL.");
+        return 10*i+17;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"An error should follow (subsection string is NULL)");
+    subset = psImageSubsection(original,NULL);
+    if (subset != NULL) {
+        psError(__func__,"psImageSubsection didn't return NULL when subsection was NULL.");
+        return 10*i+18;
+    }
+
+    psFree(original);
+
+    return 0;
+}
+
+static int testImageTrim(void)
+{
+    int r = 200;
+    int c = 300;
+    int qtrR = r/4;
+    int qtrC = c/4;
+    int halfR = r/2;
+    int halfC = c/2;
+
+    psImage* image = psImageAlloc(c,r,PS_TYPE_F32);
+    for (int row = 0; row < image->numRows; row++) {
+        for (int col = 0; col < image->numCols; col++) {
+            image->data.F32[row][col] = (psF32)col + (psF32)row/1000.0f;
+        }
+    }
+
+    /*
+        1. invoke psImageTrim with non-NULL image, and a valid region 
+           x0,y0->x1,y1 (using only positive values). Verify that:
+            a. the return psImage is the same as the input psImage.
+            b. the size of the psImage is x1-x0 by y1-y0.
+            c. the pixel values coorespond to the region [x0:x1-1,y0:y1-1].
+    */
+    psImage* image1 = psImageCopy(NULL,image,PS_TYPE_F32);
+    psImage* image2 = psImageTrim(image1,qtrC,qtrR,qtrC+halfC,qtrR+halfR);
+
+    if (image1 != image2) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not same as input value.  Not done in-place?");
+        return 1;
+    }
+
+    if (image2->numCols != halfC ||
+            image2->numRows != halfR) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "The resulting image size was %dx%d, but should be %dx%d.",
+                 image2->numCols, image2->numRows,
+                 halfC, halfR);
+        return 2;
+    }
+
+    for (int row = 0; row < image2->numRows; row++) {
+        for (int col = 0; col < image2->numCols; col++) {
+            if (fabsf(image2->data.F32[row][col] - image->data.F32[row+qtrR][col+qtrC]) > FLT_EPSILON) {
+                psLogMsg(__func__,PS_LOG_ERROR,
+                         "The value at (%d,%d) was %g, but should be %g.",
+                         col,row,
+                         image2->data.F32[row][col],
+                         image->data.F32[row+qtrR][col+qtrC]);
+                return 3;
+            }
+        }
+    }
+
+    /*
+        2. invoke psImageTrim with non-NULL image and valid region where x1=0, 
+           y1=0. Verify that:
+            a. the return psImage size is numCols-x0 by numRows-y0
+            b. the pixel values coorespond to the region 
+               [x0:numCols-1,y0:numRows-1].
+    */
+    image1 = psImageCopy(image1,image,PS_TYPE_F32);
+    image2 = psImageTrim(image1,qtrC,qtrR,0,0);
+
+    if (image1 != image2) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not same as input value.  Not done in-place?");
+        return 11;
+    }
+
+    if (image2->numCols != image->numCols-qtrC ||
+            image2->numRows != image->numRows-qtrR) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "The resulting image size was %dx%d, but should be %dx%d.",
+                 image2->numCols, image2->numRows,
+                 image->numCols-qtrC, image->numRows-qtrR);
+        return 12;
+    }
+
+    for (int row = 0; row < image2->numRows; row++) {
+        for (int col = 0; col < image2->numCols; col++) {
+            if (fabsf(image2->data.F32[row][col] -
+                      image->data.F32[row+qtrR][col+qtrC]) > FLT_EPSILON) {
+                psLogMsg(__func__,PS_LOG_ERROR,
+                         "The value at (%d,%d) was %g, but should be %g.",
+                         col,row,
+                         image2->data.F32[row][col],
+                         image->data.F32[row+qtrR][col+qtrC]);
+                return 13;
+            }
+        }
+    }
+
+    /*
+        4. invoke psImageTrim with x1<0, y1<0. Verify:
+            a. the psImage size is (numCols+x1)-x0 by (numRows+y1)-y0.
+            b. the pixel values coorespond to the region 
+               [x0:numCols+x1-1,y0:numRows+y1-1].
+
+    */
+    image1 = psImageCopy(image1,image,PS_TYPE_F32);
+    image2 = psImageTrim(image1,qtrC,qtrR,-qtrC,-qtrR);
+
+    if (image1 != image2) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not same as input value.  Not done in-place?");
+        return 21;
+    }
+
+    if (image2->numCols != image->numCols-qtrC-qtrC ||
+            image2->numRows != image->numRows-qtrR-qtrR) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "The resulting image size was %dx%d, but should be %dx%d.",
+                 image2->numCols, image2->numRows,
+                 image->numCols-qtrC, image->numRows-qtrR);
+        return 22;
+    }
+
+    for (int row = 0; row < image2->numRows; row++) {
+        for (int col = 0; col < image2->numCols; col++) {
+            if (fabsf(image2->data.F32[row][col] -
+                      image->data.F32[row+qtrR][col+qtrC]) > FLT_EPSILON) {
+                psLogMsg(__func__,PS_LOG_ERROR,
+                         "The value at (%d,%d) was %g, but should be %g.",
+                         col,row,
+                         image2->data.F32[row][col],
+                         image->data.F32[row+qtrR][col+qtrC]);
+                return 23;
+            }
+        }
+    }
+
+    psFree(image2);
+
+    /*
+        6. invoke psImageTrim with image=NULL Verify:
+            a. execution does not cease.
+            b. return value is NULL
+            c. appropriate error is generated.
+    */
+
+    image2 = psImageTrim(NULL,qtrC,qtrR,0,0);
+
+    if (image2 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not return NULL given a NULL input image.");
+        return 31;
+    }
+    psErr* err = psErrorLast();
+    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not generate an appropriate error for NULL input image.");
+        psErrorStackPrint(stderr,"Error Stack:");
+        return 32;
+    }
+    psFree(err);
+
+    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
+    image2 = psImageTrim(image1,-1,0,0,0);
+
+    if (image2 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not return NULL given x0=-1.");
+        return 33;
+    }
+    err = psErrorLast();
+    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not generate an appropriate error for x0=-1.");
+        psErrorStackPrint(stderr,"Error Stack:");
+        return 34;
+    }
+    psFree(err);
+
+    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
+    image2 = psImageTrim(image1,0,-1,0,0);
+
+    if (image2 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not return NULL given y0=-1.");
+        return 35;
+    }
+    err = psErrorLast();
+    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not generate an appropriate error for y0=-1.");
+        psErrorStackPrint(stderr,"Error Stack:");
+        return 36;
+    }
+    psFree(err);
+
+    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
+    image2 = psImageTrim(image1,0,0,image->numCols+1,0);
+
+    if (image2 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not return NULL given x1=numCols+1.");
+        return 37;
+    }
+    err = psErrorLast();
+    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not generate an appropriate error for x1=numCols+1.");
+        psErrorStackPrint(stderr,"Error Stack:");
+        return 38;
+    }
+    psFree(err);
+
+    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
+    image2 = psImageTrim(image1,0,0,0,image->numRows+1);
+
+    if (image2 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not return NULL given y1=numRows+1.");
+        return 39;
+    }
+    err = psErrorLast();
+    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not generate an appropriate error for y1=numRows+1.");
+        psErrorStackPrint(stderr,"Error Stack:");
+        return 40;
+    }
+    psFree(err);
+
+    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
+    image2 = psImageTrim(image1,0,0,-image->numCols,0);
+
+    if (image2 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not return NULL given x1=-numCols.");
+        return 41;
+    }
+    err = psErrorLast();
+    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not generate an appropriate error for x1=-numCols.");
+        psErrorStackPrint(stderr,"Error Stack:");
+        return 42;
+    }
+    psFree(err);
+
+    image1 = psImageCopy(NULL,image,PS_TYPE_F32);
+    image2 = psImageTrim(image1,0,0,0,-image->numRows);
+
+    if (image2 != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not return NULL given y1=-numRows.");
+        return 41;
+    }
+    err = psErrorLast();
+    if (err == NULL || err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageTrim did not generate an appropriate error for y1=-numRows.");
+        psErrorStackPrint(stderr,"Error Stack:");
+        return 42;
+    }
+    psFree(err);
+
+    psFree(image);
+    return 0;
+}
+
+static int testImageCut(void)
+{
+    int c = 300;
+    int r = 200;
+    int numPoints = 15;
+    float startCol[] = { 40,150, 40,  0,280, 40,280, -1,300, 20, 20, 20, 20, 20, 20};
+    float endCol[] =   {240,150,240,299, 40,240, 40,240,240, -1,300,240,240,240,240};
+    float startRow[] = { 20, 10,100,  0, 20,180,180, 10, 10, 10, 10, -1,200, 10, 10};
+    float endRow[] =   {160,180,100,199,160, 10, 10,180,180,180,180,180,180, -1,200};
+    bool success[] = {true,true,true,true,true,true,true,false,false,false,false,false,false,false,false};
+    unsigned int length = 100;
+
+    psImage* image = psImageAlloc(c,r,PS_TYPE_F32);
+    psImage* mask = psImageAlloc(c,r,PS_TYPE_MASK);
+    for (int row = 0; row < image->numRows; row++) {
+        for (int col = 0; col < image->numCols; col++) {
+            image->data.F32[row][col] = (psF32)col + (psF32)row/1000.0f;
+            if ((row & 0x0F) == 0) {
+                mask->data.PS_TYPE_MASK_DATA[row][col] = 1;
+            } else {
+                mask->data.PS_TYPE_MASK_DATA[row][col] = 0;
+            }
+        }
+    }
+    psVector* rows = psVectorAlloc(length,PS_TYPE_F32);
+    psVector* cols = psVectorAlloc(length,PS_TYPE_F32);
+
+    psVector* result = NULL;
+    for (int n = 0; n < numPoints; n++) {
+        psVector* orig = result;
+        if (! success[n]) {
+            psLogMsg(__func__,PS_LOG_INFO,"The following should be an error.");
+        }
+        if (n == 1) {
+            result = psImageCut(result,
+                                cols,rows,
+                                image,
+                                NULL,0,
+                                startCol[n], startRow[n],
+                                endCol[n], endRow[n],
+                                length,
+                                PS_INTERPOLATE_FLAT);
+        } else {
+            result = psImageCut(result,
+                                cols,rows,
+                                image,
+                                mask,1,
+                                startCol[n], startRow[n],
+                                endCol[n], endRow[n],
+                                length,
+                                PS_INTERPOLATE_FLAT);
+        }
+
+        if (success[n]) {
+            if (result == NULL) {
+                psLogMsg(__func__,PS_LOG_ERROR,
+                         "psImageCut returned NULL instead of a valid result.");
+                return n*10+1;
+            }
+
+            if (orig != NULL && orig != result) {
+                psLogMsg(__func__,PS_LOG_ERROR,
+                         "psImageCut didn't recycle the out parameter properly.");
+                return n*10+2;
+            }
+
+            float deltaRow = (endRow[n]-startRow[n])/(length-1);
+            float deltaCol = (endCol[n]-startCol[n])/(length-1);
+            psF32 truth;
+            for (int i = 0; i < length; i++) {
+                float x = (float)startCol[n]+(float)i*deltaCol;
+                float y = (float)startRow[n]+(float)i*deltaRow;
+                if (n == 1) {
+                    truth = psImagePixelInterpolate( image, x, y,
+                                                     NULL,0,0,PS_INTERPOLATE_FLAT);
+                } else {
+                    truth = psImagePixelInterpolate( image, x, y,
+                                                     mask,1,0,PS_INTERPOLATE_FLAT);
+                }
+                if (fabs(result->data.F32[i]-truth) > FLT_EPSILON) {
+                    psLogMsg(__func__,PS_LOG_ERROR,
+                             "Bad result in position %d; Found %g but expected %g.",
+                             i, result->data.F32[i], truth);
+                    return n*10+5;
+                }
+                if (fabsf(x - cols->data.F32[i]) > FLT_EPSILON ||
+                        fabsf(y - rows->data.F32[i]) > FLT_EPSILON) {
+                    psLogMsg(__func__,PS_LOG_ERROR,
+                             "Bad resulting col/row at index %d; Found (%g,%g) but expected (%g,%g).",
+                             i, cols->data.F32[i], rows->data.F32[i], x, y);
+                    return n*10+6;
+                }
+            }
+        } else {
+            if (result != NULL) {
+                psLogMsg(__func__,PS_LOG_ERROR,
+                         "psImageCut did not return NULL with a cut of (%g,%g)->(%g,%g).",
+                         startCol[n],startRow[n],endCol[n],endRow[n]);
+                return n*10+7;
+            }
+            psErr* err = psErrorLast();
+            if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+                psLogMsg(__func__,PS_LOG_ERROR,
+                         "psImageCut did not generate proper error message.");
+                return 105;
+            }
+            psFree(err);
+        }
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (NULL image).");
+    result = psImageCut(result,
+                        cols,rows,
+                        NULL,
+                        mask,1,
+                        startCol[0], startRow[0],
+                        endCol[0], endRow[0],
+                        length,
+                        PS_INTERPOLATE_FLAT);
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageCut did not return NULL given NULL image.");
+        return 100;
+    }
+    psErr* err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageCut did not generate proper error message given NULL image.");
+        return 101;
+    }
+    psFree(err);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (length=0).");
+    result = psImageCut(result,
+                        cols,rows,
+                        image,
+                        mask,1,
+                        startCol[0], startRow[0],
+                        endCol[0], endRow[0],
+                        0,
+                        PS_INTERPOLATE_FLAT);
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageCut did not return NULL given length=0.");
+        return 102;
+    }
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageCut did not generate proper error message given length=0.");
+        return 103;
+    }
+    psFree(err);
+
+    psFree(result);
+    psFree(image);
+    psFree(mask);
+    psFree(rows);
+    psFree(cols);
+
+    return 0;
+}
+
+static int testImageRadialCut(void)
+{
+    int c = 300;
+    int r = 200;
+    int centerX = c/2;
+    int centerY = r/2;
+    psErr* err = NULL;
+
+    psImage* image = psImageAlloc(c,r,PS_TYPE_F32);
+    psImage* mask = psImageAlloc(c,r,PS_TYPE_MASK);
+    for (int row = 0; row < image->numRows; row++) {
+        for (int col = 0; col < image->numCols; col++) {
+            image->data.F32[row][col] = sqrtf((col-centerX)*(col-centerX)+(row-centerY)*(row-centerY));
+            if ((row & 0x0F) == 0) {
+                mask->data.PS_TYPE_MASK_DATA[row][col] = 1;
+            } else {
+                mask->data.PS_TYPE_MASK_DATA[row][col] = 0;
+            }
+        }
+    }
+
+    psStats* stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    psVector* radii = psVectorAlloc(10,PS_TYPE_F32);
+    for (int i=0; i < 10; i++) {
+        radii->data.F32[i] = 10+i*10;
+    }
+
+    psVector* result = NULL;
+
+    result = psImageRadialCut(result,image,mask,1,centerX,centerY,radii,stat);
+
+    if (result == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value of NULL unexpected.");
+        return 1;
+    }
+
+    if (result->type.type != PS_TYPE_F64) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return type not psF64, as expected.");
+        return 2;
+    }
+
+    for (int i=0; i < 9; i++) {
+        if (fabs(result->data.F64[i] - (15.0+i*10)) > 1) {
+            psLogMsg(__func__,PS_LOG_ERROR,
+                     "Result was not as expected for radii #%d (%g, expected %d +/- 1)",
+                     result->data.F64[i], (15.0+i*10) );
+            return 3+i;
+        }
+    }
+
+    // again, but without mask
+    psVector* orig = result;
+    result = psImageRadialCut(result,image,NULL,1,centerX,centerY,radii,stat);
+
+    if (result == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value of NULL unexpected.");
+        return 12;
+    }
+
+    if (result != orig) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value of is not same as input parameter 'out'.");
+        return 13;
+    }
+
+    for (int i=0; i < 9; i++) {
+        if (fabs(result->data.F64[i] - (15.0+i*10)) > 1) {
+            psLogMsg(__func__,PS_LOG_ERROR,
+                     "Result was not as expected for radii #%d (%g, expected %d +/- 1)",
+                     result->data.F64[i], (15.0+i*10) );
+            return 14+i;
+        }
+    }
+
+    // NULL input image...
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,NULL,NULL,1,centerX,centerY,radii,stat);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 23;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 24;
+    }
+    psFree(err);
+
+    // NULL input radii...
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,image,mask,1,centerX,centerY,NULL,stat);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 23;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 24;
+    }
+    psFree(err);
+
+    // NULL input stat...
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,image,mask,1,centerX,centerY,radii,NULL);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 23;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 24;
+    }
+    psFree(err);
+
+    // Bad center X
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,image,mask,1,
+                              c+1,centerY,radii,stat);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 25;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 26;
+    }
+    psFree(err);
+
+    // Bad center Y
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,image,mask,1,
+                              centerX,r+1,radii,stat);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 27;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 28;
+    }
+    psFree(err);
+
+    // Bad mask type (N.B., swapped image/mask to do this)
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,mask,image,1,
+                              centerX,r+1,radii,stat);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 29;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_TYPE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 30;
+    }
+    psFree(err);
+
+    // Bad mask size
+    psImage* mask2 = psImageAlloc(c/2,r/2,PS_TYPE_MASK);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,image, mask2, 1,
+                              centerX,centerY,radii,stat);
+    psFree(mask2);
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 31;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_SIZE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 32;
+    }
+    psFree(err);
+
+    // Bad radii size
+    psVector* radii2 = psVectorAlloc(1,PS_TYPE_MASK);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,image, mask, 1,
+                              centerX,centerY,radii2,stat);
+    psFree(radii2);
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 33;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_SIZE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 34;
+    }
+    psFree(err);
+
+    // bad input stat option...
+    stat->options = 0;
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    result = psImageRadialCut(result,image,mask,1,centerX,centerY,radii,stat);
+    stat->options = PS_STAT_SAMPLE_MEAN;
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "Return value not NULL as expected.");
+        return 35;
+    }
+
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psImageRadialCut did not generate proper error message.");
+        return 36;
+    }
+    psFree(err);
+
+    psFree(image);
+    psFree(mask);
+    psFree(radii);
+    psFree(stat);
+    psFree(result);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/image/tst_psImageFFT.c
===================================================================
--- /branches/rel3/psLib/test/image/tst_psImageFFT.c	(revision 2163)
+++ /branches/rel3/psLib/test/image/tst_psImageFFT.c	(revision 2163)
@@ -0,0 +1,451 @@
+/** @file  tst_psImageFFT.c
+ *
+ *  @brief Contains the tests for psFFT.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-13 19:50:12 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <math.h>
+#include <float.h>
+
+#include "psTest.h"
+#include "pslib.h"
+
+#define GENIMAGE(img,c,r,TYP, valueFcn) \
+img = psImageAlloc(c,r,PS_TYPE_##TYP); \
+for (unsigned int row=0;row<r;row++) { \
+    ps##TYP* imgRow = img->data.TYP[row]; \
+    for (unsigned int col=0;col<c;col++) { \
+        imgRow[col] = (ps##TYP)(valueFcn); \
+    } \
+}
+
+static int testImageFFT(void);
+static int testImageRealImaginary(void);
+static int testImageComplex(void);
+static int testImageConjugate(void);
+static int testImagePowerSpectrum(void);
+
+testDescription tests[] = {
+                              {
+                                  testImageFFT,632,"psImageFFT",0,false
+                              },
+                              {
+                                  testImageRealImaginary,633,"psImageRealImaginary",0,false
+                              },
+                              {
+                                  testImageComplex,634,"psImageComplex",0,false
+                              },
+                              {
+                                  testImageConjugate,635,"psImageConjugate",0,false
+                              },
+                              {
+                                  testImagePowerSpectrum,636,"psImagePowerSpectrum",0,false
+                              },
+                              {
+                                  NULL
+                              }
+                          };
+
+int main(int argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    return (! runTestSuite(stderr,"psFFT",tests,argc,argv) );
+}
+
+int testImageFFT(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* img3 = NULL;
+    unsigned int m = 128;
+    unsigned int n = 64;
+    psImage* img4 = NULL;
+    psImage* img5 = NULL;
+
+    /*
+    1. assign a image to a radial sinisoid
+    2. perform a forward transform
+    3. verify that the only significant component cooresponds to the freqency of the input in step 1.
+    4. perform a reverse transform
+    5. compare to original (should be equal to within a reasonable error)
+    */
+
+    // 1. assign a image to a radial sinisoid
+    GENIMAGE(img,m,n,F32, sinf((32.0f-row)/16.0f*M_PI)+sinf((64.0f-col)/32.0f*M_PI));
+
+    // 2. perform a forward transform
+    img2 = psImageFFT(img2,img,PS_FFT_FORWARD);
+    if (img2->type.type != PS_TYPE_C32) {
+        psError(__func__,"FFT didn't produce complex values?");
+        return 1;
+    }
+    if (img2->numCols != m || img2->numRows != n) {
+        psError(__func__,"FFT didn't produce proper size result (%dx%d vs. expected %dx%d).",
+                img2->numCols,img2->numRows,m,n);
+        return 2;
+    }
+
+    // 3. verify that the only significant component cooresponds to the freqency of the input in step 1.
+    for (unsigned int row=0;row<n;row++) {
+        psC32* img2Row = img2->data.C32[row];
+        for (unsigned int col=0;col<m;col++) {
+            psF32 mag = cabsf(img2Row[col])/m/n;
+            if (mag > 0.1f) {
+                // must be (0,1) or (0,n-1) or (1,0) or (n-1,0)
+                if (! (col == 0 && (row == 1 || row == n-1))
+                        && ! (row == 0 && (col==1 || col == n-1)) ) {
+                    psError(__func__,"Result invalid at %d,%d (%.2f)",col,row,mag);
+                    return 3;
+                }
+            } else
+                if ( (col == 0 && (row == 1 || row == n-1))
+                        || (row == 0 && (col==1 || col == n-1)) ) {
+                    psError(__func__,"Result invalid at %d,%d (%.2f)",col,row,mag);
+                    return 4;
+                }
+        }
+    }
+
+
+    // 4. perform a reverse transform
+    img3 = psImageFFT(img3,img2,PS_FFT_REVERSE);
+
+    if (img3->type.type != PS_TYPE_C32) {
+        psError(__func__,"FFT didn't produce complex values?");
+        return 5;
+    }
+
+    if (img3->numCols != m || img3->numRows != n) {
+        psError(__func__,"FFT didn't produce proper size result (%dx%d vs. expected %dx%d).",
+                img3->numCols,img3->numRows,m,n);
+        return 6;
+    }
+
+    for (unsigned int row=0;row<n;row++) {
+        psC32* img3Row = img3->data.C32[row];
+        psF32* imgRow = img->data.F32[row];
+        for (unsigned int col=0;col<m;col++) {
+            psF32 pixel = creal(img3Row[col])/m/n;
+            if (fabsf(pixel-imgRow[col]) > 0.1) {
+                psError(__func__,"Reverse FFT didn't give original image back (%d,%d %.2f vs %.2f)",
+                        col,row,pixel,imgRow[col]);
+                return 7;
+            }
+        }
+    }
+
+    // 4. perform a reverse transform to real result
+    img3 = psImageFFT(img3,img2,PS_FFT_REVERSE|PS_FFT_REAL_RESULT);
+
+    if (img3->type.type != PS_TYPE_F32) {
+        char* typeStr;
+        PS_TYPE_NAME(typeStr,img3->type.type)
+        psError(__func__,"FFT asked to make real result, but I got a %s type image?",typeStr);
+        return 8;
+    }
+
+    if (img3->numCols != m || img3->numRows != n) {
+        psError(__func__,"FFT didn't produce proper size result (%dx%d vs. expected %dx%d).",
+                img3->numCols,img3->numRows,m,n);
+        return 9;
+    }
+
+    for (unsigned int row=0;row<n;row++) {
+        psF32* img3Row = img3->data.F32[row];
+        psF32* imgRow = img->data.F32[row];
+        for (unsigned int col=0;col<m;col++) {
+            psF32 pixel = img3Row[col]/m/n;
+            if (fabsf(pixel-imgRow[col]) > 0.1) {
+                psError(__func__,"Reverse FFT didn't give original image back (%d,%d %.2f vs %.2f)",
+                        col,row,pixel,imgRow[col]);
+                return 10;
+            }
+        }
+    }
+
+    // check if error occurs if FORWARD and REVERSE are both given.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    if (psImageFFT(NULL,img2,PS_FFT_REVERSE|PS_FFT_FORWARD) != NULL) {
+        psError(__func__,"PS_FFT_REVERSE|PS_FFT_FORWARD option produced something?");
+        return 11;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    if (psImageFFT(NULL,img2,PS_FFT_FORWARD|PS_FFT_REAL_RESULT) != NULL) {
+        psError(__func__,"PS_FFT_FORWARD|PS_FFT_REAL_RESULT option produced something?");
+        return 12;
+    }
+
+    /* Verify return null and program execution doesn't stop if input image is null */
+    img4 = psImageFFT(NULL,NULL,PS_FFT_FORWARD);
+    if (img4 != NULL ) {
+        psError(__func__,"psImageFFT should return null for a null input image.");
+        return 10;
+    }
+
+    /* Verify return null and program execution doesn't stop if input image is invalid direction */
+    GENIMAGE(img4,8,8,S8,row+col);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate error for invalid direction.");
+    img5 = psImageFFT(NULL,img4,PS_FFT_REAL_RESULT);
+    if (img5 != NULL) {
+        psError(__func__,"psImageFFT should return null for an invalid FFT direction.");
+        return 11;
+    }
+    psFree(img4);
+
+    psFree(img);
+    psFree(img2);
+    psFree(img3);
+
+    return 0;
+}
+
+int testImageRealImaginary(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* img3 = NULL;
+    unsigned int m = 128;
+    unsigned int n = 64;
+
+    /*
+    1. create a C32 complex vector with distinctly different real and imaginary parts.
+    2. call psImageReal and psImageImaginary
+    3. compare results to the real/imaginary components of input
+    */
+
+    // 1. create a C32 complex vector with distinctly different real and imaginary parts.
+    GENIMAGE(img,m,n,C32, row + I * col);
+
+    // 2. call psImageReal and psImageImaginary
+    img2 = psImageReal(img2,img);
+    if (img2 == NULL) {
+        psError(__func__,"psImageReal returned a NULL?");
+        return 1;
+    }
+    if (img2->type.type != PS_TYPE_F32) {
+        psError(__func__,"psImageReal returned a wrong type (%d)?",
+                img2->type.type);
+        return 2;
+    }
+
+    img3 = psImageImaginary(img3,img);
+    if (img3 == NULL) {
+        psError(__func__,"psImageImaginary returned a NULL?");
+        return 3;
+    }
+    if (img3->type.type != PS_TYPE_F32) {
+        psError(__func__,"psImageImaginary returned a wrong type (%d)?",
+                img3->type.type);
+        return 4;
+    }
+
+    // 3. compare results to the real/imaginary components of input
+    for (unsigned int row=0;row<n;row++) {
+        psF32* img2Row = img2->data.F32[row];
+        psF32* img3Row = img3->data.F32[row];
+        for (unsigned int col=0;col<m;col++) {
+            if (fabsf(img2Row[col] - row) > FLT_EPSILON) {
+                psError(__func__,"psImageReal didn't return the real portion at n=%d",
+                        n);
+                return 5;
+            }
+            if (fabsf(img3Row[col] - col) > FLT_EPSILON) {
+                psError(__func__,"psImageImaginary didn't return the imag portion at n=%d",
+                        n);
+                return 6;
+            }
+        }
+    }
+
+    psFree(img);
+    psFree(img2);
+    psFree(img3);
+
+    return 0;
+}
+
+int testImageComplex(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* img3 = NULL;
+    unsigned int m = 128;
+    unsigned int n = 64;
+
+    /*
+    1. create two unique psF32 vectors of the same size
+    2. call psImageComplex
+    3. verify that the result is a psC32
+    4. use crealf and cimagf on step 2 results
+    5. compare step 4 results to input.
+
+    6. create a psF32 and a psF64 vector of the same size
+    7. call psImageComplex
+    8. verify that an appropriate error occurred.
+
+    9. create two psf32 vectors of different sizes
+    10. call psImageComplex
+    11. verify thet an appropriate error occurred.
+    */
+
+    // 1. create two unique psF32 vectors of the same size
+    GENIMAGE(img,m,n,F32,row);
+    GENIMAGE(img2,m,n,F32,col);
+
+    // 2. call psImageComplex
+    img3 = psImageComplex(img3,img,img2);
+
+    // 3. verify that the result is a psC32
+    if (img3->type.type != PS_TYPE_C32) {
+        psError(__func__,"Image Type from psImageComplex is not complex? (%d)",
+                img3->type.type);
+        return 1;
+    }
+
+    // 4. call psImageReal and psImageImaginary on step 2 results (not needed, just use crealf/cimagf)
+    // 5. compare step 4 results to input.
+    for (unsigned int row=0;row<n;row++) {
+        psC32* img3Row = img3->data.C32[row];
+        for (unsigned int col=0;col<m;col++) {
+            if (fabsf(crealf(img3Row[col]) - row) > FLT_EPSILON ||
+                    fabsf(cimagf(img3Row[col]) - col) > FLT_EPSILON) {
+                psError(__func__,"psImageComplex result is invalid (%d,%d, %.2f+%.2fi)",
+                        col,row,crealf(img3Row[col]),cimagf(img3Row[col]));
+                return 2;
+            }
+        }
+    }
+
+    // 6. create a psF32 and a psF64 image of the same size
+    img2 = psImageRecycle(img2,m,n,PS_TYPE_F64);
+
+    // 7. call psImageComplex
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error (type mismatch).");
+    img3 = psImageComplex(img3,img,img2);
+    // 8. verify that an appropriate error occurred. (this partially has to be done via inspection)
+    if (img3 != NULL) {
+        psError(__func__,"psImageComplex returned a image though input types mismatched.");
+        return 3;
+    }
+
+    // 9. create two psf32 vectors of different sizes
+    img2 = psImageRecycle(img2,m/2,n,PS_TYPE_F32);
+
+    // 10. call psImageComplex
+    psLogMsg(__func__,PS_LOG_INFO, "Following should be an error (size mismatch).");
+    img3 = psImageComplex(img3,img,img2);
+
+    // 11. verify thet an appropriate error occurred.
+    if (img3 != NULL) {
+        psError(__func__,"psImageComplex returned a image though input sizes mismatched.");
+        return 4;
+    }
+
+    psFree(img);
+    psFree(img2);
+    psFree(img3);
+
+    return 0;
+}
+
+int testImageConjugate(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    unsigned int m = 128;
+    unsigned int n = 64;
+
+    /*
+    1. create a psC32 with unique real and imaginary values.
+    2. call psImageConjugate
+    3. verify result is psC32
+    4. verify each value is conjugate of input (a+bi -> a-bi)
+    */
+
+    // 1. create a psC32 with unique real and imaginary values.
+    GENIMAGE(img,m,n,C32, row + I * col);
+
+    // 2. call psImageConjugate
+    img2 = psImageConjugate(img2,img);
+
+    // 3. verify result is psC32
+    if (img2->type.type != PS_TYPE_C32) {
+        psError(__func__,"the psImageConjugate didn't return a C32 image.");
+        return 1;
+    }
+
+    // 4. verify each value is conjugate of input (a+bi -> a-bi)
+    for (unsigned int row=0;row<n;row++) {
+        psC32* img2Row = img2->data.C32[row];
+        for (unsigned int col=0;col<m;col++) {
+            if (fabsf(crealf(img2Row[col]) - row) > FLT_EPSILON ||
+                    fabsf(cimagf(img2Row[col]) + col) > FLT_EPSILON) {
+                psError(__func__,"psImageComplex result is invalid (%d,%d, %.2f+%.2fi)",
+                        col,row,crealf(img2Row[col]),cimagf(img2Row[col]));
+                return 2;
+            }
+        }
+    }
+
+    psFree(img);
+    psFree(img2);
+
+    return 0;
+}
+
+int testImagePowerSpectrum(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    unsigned int m = 128;
+    unsigned int n = 64;
+
+    /*
+    1. create a psC32 vector with unique real and imaginary components
+    2. call psImagePowerSpectrum
+    3. verify result is psF32
+    4. verify the values are the square of the absolute values of the original
+    */
+
+    // 1. create a psC32 vector with unique real and imaginary components
+    GENIMAGE(img,m,n,C32, row + I * col);
+
+    // 2. call psImagePowerSpectrum
+    img2 = psImagePowerSpectrum(img2,img);
+
+    // 3. verify result is psF32
+    if (img2->type.type != PS_TYPE_F32) {
+        psError(__func__,"the type was not PS_TYPE_F32.");
+        return 1;
+    }
+
+    // 4. verify the values are the square of the absolute values of the original
+    for (unsigned int row=0;row<n;row++) {
+        psC32* imgRow = img->data.C32[row];
+        psF32* img2Row = img2->data.F32[row];
+        for (unsigned int col=0;col<m;col++) {
+            psF32 power = cabs(imgRow[col]);
+            power *= power/n/n/m/m;
+
+            if (fabsf(img2Row[col] - power) > 2.0f*FLT_EPSILON) {
+                psError(__func__,"psImagePowerSpectrum result is invalid (%d,%d, %.2f vs %.2f)",
+                        col,row,img2Row[col],power);
+                return 2;
+            }
+        }
+    }
+
+    psFree(img);
+    psFree(img2);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/image/tst_psImageIO.c
===================================================================
--- /branches/rel3/psLib/test/image/tst_psImageIO.c	(revision 2163)
+++ /branches/rel3/psLib/test/image/tst_psImageIO.c	(revision 2163)
@@ -0,0 +1,399 @@
+/** @file  tst_psImageIO.c
+ *
+ *  @brief Contains the tests for psImageIO.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-02 02:09:21 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include <math.h>
+#include <float.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fitsio.h>
+
+#include "psTest.h"
+#include "pslib.h"
+
+#define GENIMAGE(img,c,r,TYP, valueFcn) \
+img = psImageAlloc(c,r,PS_TYPE_##TYP); \
+for (unsigned int row=0;row<r;row++) { \
+    ps##TYP* imgRow = img->data.TYP[row]; \
+    for (unsigned int col=0;col<c;col++) { \
+        imgRow[col] = (ps##TYP)(valueFcn); \
+    } \
+}
+
+static int testImageRead(void);
+static int testImageWrite(void);
+
+testDescription tests[] = {
+                              {
+                                  testImageRead,567,"psImageReadSection",0,false
+                              },
+                              {
+                                  testImageWrite,569,"psImageWriteSection",0,false
+                              },
+                              {
+                                  NULL
+                              }
+                          };
+
+int main(int argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    if (! runTestSuite(stderr,"psImage",tests,argc,argv)) {
+        psAbort(__FILE__,"One or more tests failed");
+    }
+    return 0;
+}
+
+int testImageRead(void)
+{
+    int N = 256;
+    int M = 128;
+    psImage* image = NULL;
+
+    /*
+        This function shall open the specified FITS file, read the specified data
+        and place the data into a psImage structure. This function shall generate
+        an error message and return NULL if any of the input parameters are out of
+        range, image file doesn't exist or image is zero or one dimensional.
+     
+        Verify the returned psImage structure contains expected values, if the input
+        parameter filename specifies an available FITS file with known 2dimensional
+        data, input parameters col, row, ncol, nrow, z specify data range with the
+        FITS file. Cases should include 1x1, Nx1, 1xN, NxN and MxN sub images and
+        total FITS file image. (done in macro)
+     
+        Verify the returned psImage structure is equal to the input parameter
+        'output', if specified. (done in macro)
+     
+        */
+
+    /* generate FITS file to read */
+
+    #define testReadTypeSize(m, n, readM0, readN0, readM, readN, TYP, filename) \
+    { \
+        psImage* img = NULL; \
+        psImage* img2 = NULL; \
+        psImage* img3 = NULL; \
+        psImage* img4 = NULL; \
+        /*        psImage* img_ref = NULL; */ \
+        \
+        GENIMAGE(img,m,n,TYP,row+2*col); \
+        img2 = psImageCopy(img2,img,PS_TYPE_##TYP); \
+        GENIMAGE(img3,m,n,TYP,row+2*col); \
+        psImageClip(img3,32.0,32.0,120.0,120.0); \
+        img4 = psImageCopy(img4,img3,PS_TYPE_##TYP); \
+        remove(filename); \
+        if (! psImageWriteSection(img3,0,0,1,NULL,0,filename)) { \
+            psError(__func__,"Failed to write test image %s",filename); \
+            return 1; \
+        } \
+        if (! psImageWriteSection(img,0,0,0,NULL,0,filename)) { \
+            psError(__func__,"Failed to write test image %s",filename); \
+            return 2; \
+        } \
+        if (! psImageWriteSection(img,0,0,1,NULL,1,filename)) { \
+            psError(__func__,"Failed to write test image %s",filename); \
+            return 3; \
+        } \
+        if (! psImageWriteSection(img3,0,0,0,NULL,1,filename)) { \
+            psError(__func__,"Failed to write test image %s",filename); \
+            return 4; \
+        } \
+        psFree(img); \
+        img = NULL; \
+        /*        img_ref = img = psImageAlloc(2,2,PS_TYPE_F32); */ \
+        psFree(img3); \
+        img3 = NULL; \
+        img = psImageReadSection(img,readM0,readN0,readM,readN,0,NULL,0,filename); \
+        /*        if (img_ref != img) { */ \
+        /*            psError(__func__,"psImageReadSection didn't recycle the psImage?"); */ \
+        /*            return 5; */ \
+        /*        } */ \
+        img3 = psImageReadSection(img3,readM0,readN0,readM,readN,1,NULL,0,filename); \
+        if (img3 == NULL) { \
+            psError(__func__,"Failed to read test image %s",filename); \
+            return 6; \
+        } \
+        for (unsigned int row = readN0; row < readN; row++) { \
+            ps##TYP* imgRow = img->data.TYP[row-readN0]; \
+            ps##TYP* img2Row = img2->data.TYP[row]; \
+            ps##TYP* img3Row = img3->data.TYP[row-readN0]; \
+            ps##TYP* img4Row = img4->data.TYP[row]; \
+            for (unsigned int col = readM0; col < readM; col++) { \
+                if (fabsf(imgRow[col-readM0]-img2Row[col]) > FLT_EPSILON) { \
+                    psError(__func__,"Image changed in I/O operation at %d,%d,0 (%.2f vs %.2f) for %s", \
+                            col,row,(psF32)imgRow[col-readM0],(psF32)img2Row[col],filename); \
+                    return 7; \
+                } \
+                if (fabsf(img3Row[col-readM0]-img4Row[col]) > FLT_EPSILON) { \
+                    psError(__func__,"Image changed in I/O operation at %d,%d,1 (%.2f vs %.2f) for %s", \
+                            col,row,(psF32)img3Row[col-readM0],(psF32)img4Row[col],filename); \
+                    return 8; \
+                } \
+            } \
+        } \
+        psFree(img); \
+        img = NULL; \
+        psFree(img3); \
+        img3 = NULL; \
+        img3 = psImageReadSection(img3,readM0,readN0,readM,readN,0,NULL,1,filename); \
+        img = psImageReadSection(img,readM0,readN0,readM,readN,1,NULL,1,filename); \
+        if (img == NULL) { \
+            psError(__func__,"Failed to read test image %s",filename); \
+            return 9; \
+        } \
+        for (unsigned int row = readN0; row < readN; row++) { \
+            ps##TYP* imgRow = img->data.TYP[row-readN0]; \
+            ps##TYP* img2Row = img2->data.TYP[row]; \
+            ps##TYP* img3Row = img3->data.TYP[row-readN0]; \
+            ps##TYP* img4Row = img4->data.TYP[row]; \
+            for (unsigned int col = readM0; col < readM; col++) { \
+                if (fabsf(imgRow[col-readM0]-img2Row[col]) > FLT_EPSILON) { \
+                    psError(__func__,"Image changed in I/O operation at %d,%d,0 (%.2f vs %.2f) for %s", \
+                            col,row,(psF32)imgRow[col-readM0],(psF32)img2Row[col],filename); \
+                    return 10; \
+                } \
+                if (fabsf(img3Row[col-readM0]-img4Row[col]) > FLT_EPSILON) { \
+                    psError(__func__,"Image changed in I/O operation at %d,%d,1 (%.2f vs %.2f) for %s", \
+                            col,row,(psF32)img3Row[col-readM0],(psF32)img4Row[col],filename); \
+                    return 11; \
+                } \
+            } \
+        } \
+        psFree(img); \
+        psFree(img2); \
+        psFree(img3); \
+        psFree(img4); \
+    }
+
+    #define testReadType(TYP,filename) \
+    mkdir("tmpImages",0777); \
+    testReadTypeSize(1,1,0,0,1,1,TYP,"tmpImages/1x1_" filename); \
+    testReadTypeSize(M,1,M/4,0,M/2,1,TYP,"tmpImages/Mx1_" filename); \
+    testReadTypeSize(1,N,0,N/4,1,N/2,TYP,"tmpImages/1xN_" filename); \
+    testReadTypeSize(M,N,M/4,N/4,M/2,N/2,TYP,"tmpImages/MxN_" filename);
+
+    testReadType(U8,"U8.fits");
+    //    testReadType(S8,"S8.fits");   Not a requirement
+    testReadType(S16,"S16.fits");
+    //    testReadType(U16,"U16.fits"); Not a requirement
+    testReadType(S32,"S32.fits");
+    //    testReadType(U32,"U32.fits"); Not a requirement
+    testReadType(F32,"F32.fits");
+    testReadType(F64,"F64.fits");
+
+    /*
+    Verify the returned psImage structure pointer is null, error log message is
+    generated and program execution doesn't stop, if input parameter filename
+    specifies a file that doesn't exist.
+    */
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error as file doesn't exist.");
+    image = psImageReadSection(image,0,0,M,N,0,NULL,0,"foobar.fits");
+    if (image != NULL) {
+        psError(__func__,"Image returned though filename did not exist.");
+        return 12;
+    }
+
+    /*
+    Verify the returned psImage structure pointer is null, error log message is
+    generatedand program execution doesn't stop, if input parameter filename
+    is null.Verify the returned psImage structurepointer is null, error log
+    message is generated and program execution doesn't stop, if input
+    parameters col,row, ncol, nrow and/or z specify a data range which is not
+    within the data range of the FITS file.
+    */
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error as filename is NULL.");
+    image = psImageReadSection(image,0,0,M,N,0,NULL,0,NULL);
+    if (image != NULL) {
+        psError(__func__,"Image returned though filename was NULL.");
+        return 13;
+    }
+
+    /*
+    Verify the returned psImage structure pointer is null, error log message is
+    generated and program execution doesn't stop,if input parameters extname
+    and/or extnum specify an extension which is not valid in the FITS file.
+    */
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error as extnum is invalid.");
+    image = psImageReadSection(image,0,0,M,N,0,NULL,4,"tmpImages/MxN_F32.fits");
+    if (image != NULL) {
+        psError(__func__,"Image returned though extnum was invalid.");
+        return 14;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error as extname is invalid.");
+    image = psImageReadSection(image,0,0,M,N,0,"bogus",0,"tmpImages/MxN_F32.fits");
+    if (image != NULL) {
+        psError(__func__,"Image returned though extnum was invalid.");
+        return 15;
+    }
+
+    /*
+    Verify the returned psImage structure pointer is null, error log message is
+    generated and program execution doesn't stop,if input parameter filename
+    specifies a FITS file that is zero or one dimensional.
+
+    XXX
+    N.B: since I can't write anything but 2 or 3 dimensional image, I can't
+    do this programatically at this time.  I verified that this functionality
+    exists in the source code via inspection. (line 101 in psImageIO.c for v1.3)
+    -rdd
+    */
+
+    return 0;
+}
+
+int testImageWrite(void)
+{
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    int m = 64;
+    int n = 96;
+
+    /*
+    This function shall write the specified section within a psImage structure
+    to a FITS file. If the specifiedfile exists, then data should overwrite the
+    section to write. If the specified file doesn't exist, it shall be created.
+    If an extenstion is specified, then a basic primary header data unit shall
+    be created.
+    */
+
+    /*
+    Verify a FITS file named filename is generated and contains expected
+    values, if the input parameter input contains known data values, input
+    parameters col, row, ncol, nrow specify a valid data region within psImage
+    structure.
+
+    Verify a FITS file named filename is generated and contains a primary
+    header data unit with extension with expected values, if the input
+    parameter input contains known data values, input parameters col, row,
+    ncol, nrow specify a valid data region within psImage structure and
+    extname and/or extnum specify an extenstion to write.
+
+    N.B. : these are done in testImageRead tests, see above.
+    */
+
+    /*
+    Verify a FITS file named filename is overwritten and contains
+    expected values, if the input parameter input contains known data values,
+    input parameters col, row, ncol, nrow specify a valid data region within
+    psImage structure.
+    */
+
+    GENIMAGE(img,m,n,F32,0);
+    GENIMAGE(img2,m,n,F32,row+2*col);
+    mkdir("tmpImages",0777);
+    remove
+        ("writeTest.fits")
+        ;
+    if (! psImageWriteSection(img,0,0,0,NULL,0,"tmpImages/writeTest.fits")) {
+        psError(__func__,"Couldn't write writeTest.fits.");
+        return 14;
+    }
+    if (! psImageWriteSection(img2,0,0,0,NULL,0,"tmpImages/writeTest.fits")) {
+        psError(__func__,"Couldn't overwrite writeTest.fits.");
+        return 15;
+    }
+    psFree(img);
+    psFree(img2);
+
+    // Did it really overwrite the pixel values?  Let's read it in and see.
+    img = psImageReadSection(NULL,0,0,m,n,0,NULL,0,"tmpImages/writeTest.fits");
+    if (img == NULL) {
+        psError(__func__,"Could not read in writeTest.fits.");
+        return 16;
+    }
+    for (unsigned int row=0;row<n;row++) {
+        psF32* imgRow = img->data.F32[row];
+        for (unsigned int col=0;col<m;col++) {
+            if (fabsf(imgRow[col] - (row+2*col)) > FLT_EPSILON) {
+                psError(__func__,"The image values were not overwritten at %d,%d (%.2f vs %.2f)",
+                        col,row,imgRow[col],(row+2*col));
+                return 17;
+            }
+        }
+    }
+
+    psFree(img);
+
+    /*
+    Verify false is returned and program execution is not stopped, if the input image
+    is null.
+    */
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message because input image is null.");
+    if ( psImageWriteSection(NULL,0,0,0,NULL,0,"tmpImages/writeTest.fits")) {
+        psError(__func__,"psImageWriteSection did not return false when input image is NULL.");
+        return 20;
+    }
+
+    /*
+    Verify error message generated when invalid image type is pass as the input image.
+    */
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for passing invalid image type.");
+    GENIMAGE(img,32,32,S8,row+2*col);
+    if ( psImageWriteSection(img,0,0,0,NULL,0,"tmpImages/writeTest.fits")) {
+        psError(__func__,"psImageWriteSection did not return false when input image type invalid.");
+        return 21;
+    }
+    psFree(img);
+
+    /*
+    Verify error message generated when invalid path specified for output file.
+    */
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for passing invalid image type.");
+    GENIMAGE(img,32,32,U8,row+2*col);
+    if ( psImageWriteSection(img,0,0,0,NULL,0,"panstarrs/writeFits.fits")) {
+        psError(__func__,"psImageWriteSection did not return false for invalid path name.");
+        return 22;
+    }
+
+    /*
+    Verify error message generated when an invalid FITs file is specified
+    */
+    FILE *fileptr = fopen("tmpImages/writeInvalidFile.fits","w");
+    fprintf(fileptr," ");
+    fclose(fileptr);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for passing invalid FITS file.");
+    if ( psImageWriteSection(img,0,0,0,NULL,0,"tmpImages/writeInvalidFile.fits")) {
+        psError(__func__,"psImageWriteSection did not return false for invalid FITS file.");
+        return 22;
+    }
+    remove
+        ("tmpImages/writeInvalidFile.fits");
+
+    /*
+    Verify error message when invalid extension name is provided
+    */
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for invalid extension name.");
+    if ( psImageWriteSection(img,0,0,0,"ext2",0,"tmpImages/writeTest.fits")) {
+        psError(__func__,"psImageWriteSection did not return false for invalid extension name.");
+        return 23;
+    }
+
+    /*
+    Verified error message when invalid extension number is provided
+    */
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for invalid extension number.");
+    if ( psImageWriteSection(img,0,0,0,NULL,99,"tmpImages/writeTest.fits")) {
+        psError(__func__,"psImageWriteSection did not return false for invalid extension number.");
+        return 24;
+    }
+
+    psFree(img);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/image/tst_psImageManip.c
===================================================================
--- /branches/rel3/psLib/test/image/tst_psImageManip.c	(revision 2163)
+++ /branches/rel3/psLib/test/image/tst_psImageManip.c	(revision 2163)
@@ -0,0 +1,1824 @@
+/** @file  tst_psImageManip.c
+ *
+ *  @brief Contains the tests for psImageManip.[ch]
+ *
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.29 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 01:22:59 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+
+#include <math.h>
+#include <float.h>
+#include <string.h>
+#include <stdlib.h>
+#include <string.h>                    // for memset
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "psTest.h"
+#include "pslib.h"
+#include "psType.h"
+
+static int testImageClip(void);
+static int testImageClipNAN(void);
+static int testImageClipComplexRegion(void);
+static int testImageOverlay(void);
+static int testImageRebin(void);
+static int testImageRoll(void);
+static int testImageRotate(void);
+static int testImageShift(void);
+static int testImageShiftCase(int cols, int rows, float colShift,float rowShift);
+static int testImageResample(void);
+
+testDescription tests[] = {
+                              {testImageClip,571,"psImageClip",0,false},
+                              {testImageClipNAN,572,"psImageClipNAN",0,false},
+                              {testImageClipComplexRegion,673,"psImageClipComplexRegion",0,false},
+                              {testImageOverlay,573,"psImageOverlay",0,false},
+                              {testImageRebin,559,"psImageRebin",0,false},
+                              {testImageRoll,562,"psImageRoll",0,false},
+                              {testImageRotate,560,"psImageRotate",0,false},
+                              {testImageShift,561,"psImageShift",0,false},
+                              {testImageResample,743,"psImageResample",0,false},
+                              {NULL}
+                          };
+
+int main(int argc, char* argv[])
+{
+    psLogSetLevel(PS_LOG_INFO);
+
+    return ! runTestSuite(stderr,"psImage",tests,argc,argv);
+}
+
+
+int testImageClip(void)
+{
+    psImage* img = NULL;
+    unsigned int c = 128;
+    unsigned int r = 256;
+    psF64 min;
+    psF64 max;
+    int numClipped = 0;
+    int retVal;
+
+    psLogMsg(__func__,PS_LOG_INFO,
+             "psImageClip shall limit the minimum and maximum data value within a psImage structure");
+
+    /*
+
+        psImageClip shall limit the minimum and maximum data value within a
+        psImage structure to a specified min and max value.
+
+        Verify the returned integer is equal to the number of pixels clipped,
+        if the input psImage structure contains known values and input parameters
+        min and max have know values.
+
+        Verify the psImage structure specified by the input parameter input is
+        modified to contain the expected values, if the input psImage structure
+        contains known values, min and max are specified and vmin and vmax
+        parameters are known.
+
+        Verify the retuned integer is zero, psImage structure input is unmodified
+        and program executions doesn't stop, if input parameter psImage structure
+        pointer is null.
+
+        Verify the retuned integer is zero, psImage structure input is unmodified
+        and program executions doesn't stop, if input parameter min is larger than max.
+    */
+
+    // create image
+    #define testImageClipByType(datatype) \
+    img = psImageAlloc(c,r,PS_TYPE_##datatype); \
+    for (unsigned int row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned int col=0;col<c;col++) { \
+            imgRow[col] = (ps##datatype)(row+col); \
+        } \
+    } \
+    min = (psF64)r/2.0; \
+    max = (psF64)r; \
+    \
+    retVal = psImageClip(img,min,(double)PS_MIN_##datatype,max,(double)PS_MAX_##datatype); \
+    \
+    numClipped = 0; \
+    for (unsigned int row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned int col=0;col<c;col++) { \
+            ps##datatype value = (ps##datatype)(row+col); \
+            if (value < min) { \
+                numClipped++; \
+                value = PS_MIN_##datatype; \
+            } else if (value > max) { \
+                numClipped++; \
+                value = PS_MAX_##datatype; \
+            } \
+            if (fabsf(imgRow[col]-value) > FLT_EPSILON) { \
+                psError(__func__,"Pixel value is not as expected (%g vs %g) at %u,%u", \
+                        (psF64)imgRow[col],(psF64)value,col,row); \
+                return 1; \
+            } \
+        } \
+    } \
+    if (retVal != numClipped) { \
+        psError(__func__,"Expected %d clips, but got %d", \
+                numClipped,retVal); \
+        return 2; \
+    } \
+    psFree(img);
+
+    #define testImageClipByComplexType(datatype) \
+    img = psImageAlloc(c,r,PS_TYPE_##datatype); \
+    for (unsigned int row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned int col=0;col<c;col++) { \
+            imgRow[col] = (ps##datatype)(row+I*col); \
+        } \
+    } \
+    min = (float)r/2.0f; \
+    max = (float)r; \
+    \
+    retVal = psImageClip(img,min,-1.0f,max,-2.0f); \
+    \
+    numClipped = 0; \
+    for (unsigned int row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned int col=0;col<c;col++) { \
+            ps##datatype value = row+I*col; \
+            if (cabs(value) < min) { \
+                numClipped++; \
+                value = -1.0f; \
+            } else if (cabs(value) > max) { \
+                numClipped++; \
+                value = -2.0f; \
+            } \
+            if (fabsf(creal(imgRow[col])-creal(value)) > FLT_EPSILON || \
+                    fabsf(cimag(imgRow[col])-cimag(value)) > FLT_EPSILON) { \
+                psError(__func__,"Pixel value is not as expected (%.2f+%.2fi vs %.2f+%.2fi) at %u,%u", \
+                        creal(imgRow[col]),cimag(imgRow[col]),creal(value),cimag(value),col,row); \
+                return 1; \
+            } \
+        } \
+    } \
+    if (retVal != numClipped) { \
+        psError(__func__,"Expected %d clips, but got %d", \
+                numClipped,retVal); \
+        return 2; \
+    } \
+    psFree(img);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of F64 imagery");
+    testImageClipByType(F64);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of F32 imagery");
+    testImageClipByType(F32);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of S32 imagery");
+    testImageClipByType(S32);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of S16 imagery");
+    testImageClipByType(S16);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of S8 imagery");
+    testImageClipByType(S8);
+    //    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of U32 imagery");
+    //    testImageClipByType(U32);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of U16 imagery");
+    testImageClipByType(U16);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of U8 imagery");
+    testImageClipByType(U8);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of C32 imagery");
+    testImageClipByComplexType(C32);
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping of C64 imagery");
+    testImageClipByComplexType(C64);
+
+    // Verify the retuned integer is zero, psImage structure input is unmodified
+    // and program executions doesn't stop, if input parameter psImage structure
+    // pointer is null.
+    retVal = psImageClip(NULL,min,-1.0f,max,-2.0f);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for clips of a NULL image.");
+        return 3;
+    }
+
+    // Verify the retuned integer is zero, psImage structure input is unmodified
+    // and program executions doesn't stop, if input parameter min is larger than max.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (max<min)");
+    retVal = psImageClip(img,max,-1.0f,min,-2.0f);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for clips when max < min.");
+        return 4;
+    }
+
+    // Verify program execution doesn't stop if the input image type is something
+    // other than U8, U16, S8, S16, F32, F64, C32, C64.
+    img = psImageAlloc(c,r,PS_TYPE_U32);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (invalid type)");
+    retVal = psImageClip(img,min,-1.0f,max,-2.0f);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for clip of invalid image type.");
+        return 5;
+    }
+    psFree(img);
+
+    return 0;
+}
+
+int testImageClipNAN(void)
+{
+    psImage* img = NULL;
+    unsigned int c = 128;
+    unsigned int r = 256;
+    int numClipped = 0;
+    int retVal;
+
+    psLogMsg(__func__,PS_LOG_INFO,
+             "psImageClipNaN shall modified pixel values of NaN with a specified value");
+
+    /*
+        psImageClipNaN shall modify a psImage structure with pixel values set
+        to NaN to a value specified as an input parameter.
+
+        Verify the returned integer is equal to the number of pixels modified
+        and the psImage is modified at locations where NaN pixels where
+        located to the value specified in the input parameter value.
+
+        Verify the returned integer is zero and program execution doesn't stop,
+        if the input parameter psImage structure pointer is null.
+    */
+
+    // create image
+    #define testImageClipNaNByType(datatype) \
+    img = psImageAlloc(c,r,PS_TYPE_##datatype); \
+    for (unsigned row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            if (row == col) { \
+                imgRow[col] = NAN; \
+            } else if (row+1 == col) { \
+                imgRow[col] = INFINITY; \
+            } else { \
+                imgRow[col] = (ps##datatype)(row+col); \
+            } \
+        } \
+    } \
+    \
+    retVal = psImageClipNaN(img,-1.0f); \
+    \
+    numClipped = 0; \
+    for (unsigned row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            ps##datatype value = (ps##datatype)(row+col); \
+            if ( (row == col) || (row+1 == col) ) { \
+                numClipped++; \
+                value = -1.0; \
+            } \
+            if (fabsf(imgRow[col]-value) > FLT_EPSILON) { \
+                psError(__func__,"Pixel value is not as expected (%f vs %f) at %d,%d", \
+                        imgRow[col],value,col,row); \
+                return 1; \
+            } \
+        } \
+    } \
+    if (retVal != numClipped) { \
+        psError(__func__,"Expected %d clips, but got %d", \
+                numClipped,retVal); \
+        return 2; \
+    } \
+    psFree(img);
+
+    testImageClipNaNByType(F32);
+    testImageClipNaNByType(F64);
+    testImageClipNaNByType(C32);
+    testImageClipNaNByType(C64);
+
+    // Verify the retuned integer is zero, psImage structure input is unmodified
+    // and program executions doesn't stop, if input parameter psImage structure
+    // pointer is null.
+    retVal = psImageClipNaN(NULL,-1.0f);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for clips of a NULL image.");
+        return 3;
+    }
+
+    // Verify program execution doesn't stop if the input image type is something
+    // other than F32, F64, C32, C64.
+    img = psImageAlloc(c,r,PS_TYPE_S32);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (invalid type)");
+    retVal = psImageClipNaN(img,2.0f);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for clip of invalid image type.");
+        return 4;
+    }
+    psFree(img);
+
+    return 0;
+}
+
+int testImageClipComplexRegion(void)
+{
+    psImage* img = NULL;
+    unsigned int c = 1024;
+    unsigned int r = 2048;
+    int numClipped = 0;
+    int retVal;
+
+    psLogMsg(__func__,PS_LOG_INFO,
+             "psImageClipNaN shall modified pixel values of NaN with a specified value");
+
+    /*
+    1. Create a complex image with a wide range of complex values
+
+    2. call psImageClipComplexRegion with min and max where there is at least 
+       2 pixels in the image above) that is:
+        a) real(p) < real(min) && complex(p) < complex(min),
+        b) real(p) < real(min) && complex(min) < complex(p) < complex(max)
+        c) real(min) < real(p) < real(max) && complex(p) < complex(min)
+        d) real(min) < real(p) < real(max) && complex(min) < complex(p) < complex(max)
+        e) real(p) > real(max) && complex(min) < complex(p) < complex(max)
+        f) real(pmin) < real(p) < real(max) && complex(p) > complex(max)
+        g) real(p) > real(max) && complex(p) > complex(max)
+        h) real(p) < real(min) && complex(p) > complex(max)
+        i) real(p) > real(max) && complex(p) < complex(min)
+
+    3. verify that All pixels in case (a), (b), and (c) have the value vmin
+
+    4. verify that all pixels in case (d) are unchanged from input
+
+    5. verify that all pixels in case (e), (f), (g), (h), and (i) have the 
+       value vmax
+
+    */
+
+    #define testImageClipComplexByType(datatype,MIN,MAX) /* datatype must be complex */ \
+    /* create image */ \
+    img = psImageAlloc(c,r,PS_TYPE_##datatype); \
+    for (unsigned row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            imgRow[col] = row+I*col; \
+        } \
+    } \
+    \
+    retVal = psImageClipComplexRegion(img,MIN,-1.0-1.0*I,MAX,-2.0-2.0*I); \
+    \
+    numClipped = 0; \
+    for (unsigned row=0;row<r;row++) { \
+        ps##datatype* imgRow = img->data.datatype[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            ps##datatype value = (ps##datatype)(row+I*col); \
+            if ( (row > creal(MAX)) || (col > cimag(MAX)) ) { \
+                numClipped++; \
+                value = -2.0-2.0*I; \
+            } else if ((row < creal(MIN)) || (col < cimag(MIN)) ) { \
+                numClipped++; \
+                value = -1.0-1.0*I; \
+            } \
+            if (cabs(imgRow[col]-value) > FLT_EPSILON) { \
+                psError(__func__,"Pixel value is not as expected (%g%+gi vs %g%+gi) at %d,%d", \
+                        creal(imgRow[col]),cimag(imgRow[col]),creal(value),cimag(value),col,row); \
+                return 1; \
+            } \
+        } \
+    } \
+    if (retVal != numClipped) { \
+        psError(__func__,"Expected %d clips, but got %d", \
+                numClipped,retVal); \
+        return 2; \
+    } \
+    psFree(img);
+
+    complex double min = ((double)r)/5.0+I*((double)c)/4.0;
+    complex double max = ((double)r)/3.0+I*((double)c)/2.0;
+
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping at %g%+gi to %g%+gi for psC32",
+             creal(min),cimag(min),creal(max),cimag(max));
+
+    testImageClipComplexByType(C32,min,max);
+
+    psLogMsg(__func__,PS_LOG_INFO,"Testing clipping at %g%+gi to %g%+gi for psC64",
+             creal(min),cimag(min),creal(max),cimag(max));
+    testImageClipComplexByType(C64,min,max);
+
+    //  6. Call psImageClipComplexRegion with NULL input parameter; should error
+    //     but not stop execution.
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(NULL,0,0,0,0);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for clips of a NULL image.");
+        return 3;
+    }
+
+
+    img = psImageAlloc(c,r,PS_TYPE_C32);
+    for (unsigned row=0;row<r;row++) {
+        psC32* imgRow = img->data.C32[row];
+        for (unsigned col=0;col<c;col++) {
+            imgRow[col] = row+I*col;
+        }
+    }
+
+    //  7. Call psImageClipComplexRegion with min > max; should error and return 0,
+    //     but not stop execution
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,10.0+I*1.0,-1.0,5.0+5.0*I,-2.0);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for creal(min)>creal(max).");
+        return 3;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,1.0+I*10.0,-1.0,5.0+5.0*I,-2.0);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for cimag(min)>cimag(max).");
+        return 3;
+    }
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,10.0+I*10.0,-1.0,5.0+5.0*I,-2.0);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for min>max.");
+        return 3;
+    }
+
+    //  8. Call psImageClipComplexRegion with the follow vmin/vmax values; each
+    //     should error and return 0, but not stop execution
+    //      a) vmin < datatype region's minimum
+    //      b) vmax < datatype region's minimum
+    //      c) vmin > datatype region's maximum
+    //      d) vmax > datatype region's maximum
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      -2.0*(double)FLT_MAX,
+                                      5.0+5.0*I,
+                                      0.0);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for vmin not in datatype range.");
+        return 80;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      2.0*(double)FLT_MAX,
+                                      5.0+5.0*I,
+                                      0.0);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for vmin not in datatype range.");
+        return 81;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      -2.0*(double)FLT_MAX*I,
+                                      5.0+5.0*I,
+                                      0.0);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for vmin not in datatype range.");
+        return 82;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      2.0*(double)FLT_MAX*I,
+                                      5.0+5.0*I,
+                                      0.0);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for vmin not in datatype range.");
+        return 83;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      0.0,
+                                      5.0+5.0*I,
+                                      -2.0*(double)FLT_MAX);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for vmax not in datatype range.");
+        return 84;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      0.0,
+                                      5.0+5.0*I,
+                                      2.0*(double)FLT_MAX);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for vmax not in datatype range.");
+        return 85;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      0.0,
+                                      5.0+5.0*I,
+                                      -2.0*(double)FLT_MAX*I);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for vmax not in datatype range.");
+        return 87;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error:");
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      0.0,
+                                      5.0+5.0*I,
+                                      2.0*(double)FLT_MAX*I);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for vmax not in datatype range.");
+        return 88;
+    }
+
+
+    // now check if vmin > vmax is OK
+    for (unsigned row=0;row<r;row++) {
+        psC32* imgRow = img->data.C32[row];
+        for (unsigned col=0;col<c;col++) {
+            imgRow[col] = row+I*col;
+        }
+    }
+    retVal = psImageClipComplexRegion(img,
+                                      1.0+I*1.0,
+                                      10.0,
+                                      5.0+5.0*I,
+                                      0.0);
+    if (retVal == 0) {
+        psError(__func__,"Didn't expect zero return for vmin > vmax.");
+        return 83;
+    }
+
+
+    psFree(img);
+    img = NULL;
+
+    //  9. Call psImageClipComplexRegion with the max value out of datatype's
+    //     range; should clip as expected (see step 1-5). Repeat with min value
+    //     out of datatype's range.
+
+    testImageClipComplexByType(C32,-(double)FLT_MAX*2.0-I*(double)FLT_MAX*2.0,10.0+I*10.0);
+    testImageClipComplexByType(C32,10.0+I*10.0,(double)FLT_MAX*2.0+I*(double)FLT_MAX*2.0);
+
+    // Verify program execution doesn't stop if the input image type is something
+    // other than C32, C64.
+    img = psImageAlloc(c,r,PS_TYPE_S32);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error (invalid type)");
+    retVal = psImageClipComplexRegion(img,2.0,10.0,5.0,0.0);
+    if (retVal != 0) {
+        psError(__func__,"Expected zero return for clip of invalid image type.");
+        return 84;
+    }
+    psFree(img);
+
+    return 0;
+}
+
+int testImageOverlay(void)
+{
+
+    psImage* img = NULL;
+    psImage* img2 = NULL;
+    psImage* img3 = NULL;
+    psImage* img4 = NULL;
+    unsigned int c = 128;
+    unsigned int r = 256;
+    int retVal;
+
+    /*
+    psImageSectionOverlay shall modified pixel values in a psImage structure to
+    be equal to the value of the originaldata and an overlay image with a
+    specified operation. Valid operations include =, +, -, *, /.
+
+    Verify the returned integer is zero
+    and the input parameter psImage structure is modified at the specified
+    location and range with the given overlay image and the specified
+    function. Cases should include all the valid operations. Comparison of
+    expected values should include a delta to allow for testing on
+    different platforms.
+
+    */
+
+
+
+    #define testOverlayTypeOP(DATATYPE,OP,OPSTRING) \
+    img = psImageAlloc(c,r,PS_TYPE_##DATATYPE); \
+    for (unsigned row=0;row<r;row++) { \
+        ps##DATATYPE* imgRow = img->data.DATATYPE[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            imgRow[col] = 6.0; \
+        } \
+    } \
+    img2 = psImageAlloc(c/2,r/2,PS_TYPE_##DATATYPE); \
+    for (unsigned row=0;row<r/2;row++) { \
+        ps##DATATYPE* img2Row = img2->data.DATATYPE[row]; \
+        for (unsigned col=0;col<c/2;col++) { \
+            img2Row[col] = 2.0; \
+        } \
+    } \
+    retVal = psImageOverlaySection(img,img2,c/4,r/4,OPSTRING); \
+    if (retVal != 0) { \
+        psError(__func__,"psImageOverlaySection returned non-zero %s op",OPSTRING); \
+        return 1; \
+    } \
+    for (unsigned row=0;row<r;row++) { \
+        ps##DATATYPE* imgRow = img->data.DATATYPE[row]; \
+        ps##DATATYPE* img2Row = img2->data.DATATYPE[row]; \
+        for (unsigned col=0;col<c;col++) { \
+            ps##DATATYPE val = 6.0; \
+            if ( ! (row < r/4 || row >= r/2+r/4 || col < c/4 || col >= c/2+c/4)) { \
+                val OP 2.0; \
+            } \
+            if (fabsf(imgRow[col] - val) > FLT_EPSILON) { \
+                psError(__func__,"Value incorrect at %d,%d (%.2f vs %.2f for %s)", \
+                        col,row,imgRow[col],val,OPSTRING); \
+                return 2; \
+            } \
+            if (row < r/2 && col < c/2 && fabsf(img2Row[col] - 2.0) > FLT_EPSILON) { \
+                psError(__func__,"Overlay modified at %d,%d (%.2f for %s)", \
+                        col,row,img2Row[col],OPSTRING); \
+                return 2; \
+            } \
+        } \
+    } \
+    psFree(img); \
+    psFree(img2);
+
+    #define testOverlayType(DATATYPE) \
+    testOverlayTypeOP(DATATYPE,+=,"+"); \
+    testOverlayTypeOP(DATATYPE,-=,"-"); \
+    testOverlayTypeOP(DATATYPE,*=,"*");\
+    testOverlayTypeOP(DATATYPE,/=,"/");\
+    testOverlayTypeOP(DATATYPE,=,"=");
+
+    testOverlayType(C64);
+    testOverlayType(C32);
+    testOverlayType(F64);
+    testOverlayType(F32);
+    testOverlayType(S16);
+    testOverlayType(S8);
+    testOverlayType(U16);
+    testOverlayType(U8);
+
+    /*
+    Verify the returned integer is equal to non-zero and the input psImage structure
+    is unmodified, if the overlay specified is not within the data range of the
+    input psImage structure.
+    */
+
+    img = psImageAlloc(c,r,PS_TYPE_F32);
+    for (unsigned row=0;row<r;row++) {
+        psF32* imgRow = img->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            imgRow[col] = 6.0f;
+        }
+    }
+    img2 = psImageAlloc(c,r,PS_TYPE_F32);
+    for (unsigned row=0;row<r;row++) {
+        psF32* img2Row = img2->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            img2Row[col] = 2.0f;
+        }
+    }
+    img3 = psImageAlloc(c,r,PS_TYPE_S64);
+    for (unsigned row=0;row<r;row++) {
+        psS64* img3Row = img3->data.S64[row];
+        for (unsigned col=0;col<c;col++) {
+            img3Row[col] = 6.0f;
+        }
+    }
+    img4 = psImageAlloc(c,r,PS_TYPE_S64);
+    for (unsigned row=0;row<r;row++) {
+        psS64* img4Row = img4->data.S64[row];
+        for (unsigned col=0;col<c;col++) {
+            img4Row[col] = 2.0f;
+        }
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error as overlay isn't "
+             "within image boundaries");
+    retVal = psImageOverlaySection(img,img2,c/4,r/4,"+");
+    if (retVal == 0) {
+        psError(__func__,"psImageOverlaySection returned zero even though "
+                "overlay too big");
+        return 3;
+    }
+    for (unsigned row=0;row<r;row++) {
+        psF32* imgRow = img->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            if (imgRow[col] != 6.0f) {
+                psError(__func__,"Input image modified when overlay size too big");
+                return 4;
+            }
+        }
+    }
+
+    /*
+    Verify the returned integer is equal to non-zero, the input psImage
+    structure is unmodified and program execution doesn't stop, if the
+    overlay specified is null.
+    */
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error as overlay is NULL");
+    retVal = psImageOverlaySection(img,NULL,c/4,r/4,"+");
+    if (retVal == 0) {
+        psError(__func__,"psImageOverlaySection returned zero even though "
+                "overlay too big");
+        return 5;
+    }
+    for (unsigned row=0;row<r;row++) {
+        psF32* imgRow = img->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            if (imgRow[col] != 6.0f) {
+                psError(__func__,"Input image modified when overlay NULL");
+                return 6;
+            }
+        }
+    }
+
+    /*
+    Verify the returned integer is equal to non-zero and program execution
+    doesn't stop, if the input parameter image is null.
+    */
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error as image input is NULL");
+    retVal = psImageOverlaySection(NULL,img2,c/4,r/4,"+");
+    if (retVal == 0) {
+        psError(__func__,"psImageOverlaySection returned zero even though "
+                "overlay too big");
+        return 7;
+    }
+
+    /*
+    Verify the return integer is equal to non-zero and program execution
+    doesn't stop, if the specified operator is not =,+,-,*,/
+    */
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error as operator is invalid");
+    retVal = psImageOverlaySection(img,img2,0,0,"$");
+    if (retVal == 0) {
+        psError(__func__,"psImageOverlaySection returned zero even though "
+                "overlay operator is invalid");
+        return 8;
+    }
+
+    /*
+    Verify the return integer is equal to non-zero and program execution
+    doesn't stop, if the specified operator is NULL
+    */
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error as operator is invalid");
+    retVal = psImageOverlaySection(img,img2,0,0,NULL);
+    if(retVal == 0) {
+        psError(__func__,"psImageOverlaySection returned zero even though "
+                "overlay operator is NULL");
+        return 9;
+    }
+
+    /*
+    Verify the return integer is equal to non-zero and program execution 
+    doesn't stop, if overlay image is a different type than the input image
+    */
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error as overlay is "
+             "a different type");
+    retVal = psImageOverlaySection(img,img3,0,0,"+");
+    if(retVal == 0) {
+        psError(__func__,"psImageOverlaySection returned zero eventhough "
+                " overlay image type is different than input image.");
+        return 10;
+    }
+
+    /*
+    Verify the return integer is equal to non-zero and program execution
+    doesn't stop, if invalid input and overlay images
+    */
+    psLogMsg(__func__,PS_LOG_INFO,"Following should error as overlay and "
+             "image are not valid for the psImageOverlaySection function.");
+    retVal = psImageOverlaySection(img3,img4,0,0,"+");
+    if(retVal == 0) {
+        psError(__func__,"psImageOverlaySection returned zero eventhough "
+                "overlay and image type are invalid type.");
+        return 11;
+    }
+
+    /*
+    Verify program execution doen't stop, if the overly image contains
+    zero values with division operation is specified.
+    */
+    for (unsigned row=0;row<r;row++) {
+        psF32* img2Row = img2->data.F32[row];
+        for (unsigned col=0;col<c;col++) {
+            img2Row[col] = 0.0f;
+        }
+    }
+    retVal = psImageOverlaySection(img,img2,0,0,"/");
+    if (retVal != 0) {
+        psError(__func__,"psImageOverlaySection returned non-zero when "
+                "checking divide-by-zero.");
+        return 12;
+    }
+
+    psFree(img);
+    psFree(img2);
+    psFree(img3);
+    psFree(img4);
+
+    return 0;
+}
+
+static int testImageRebin(void)
+{
+
+    /*
+    This function shall generate a rescaled version of a psImage structure 
+    derived from a specified statistics method.
+    */
+
+    psImage* in = NULL;
+    psImage* out = NULL;
+    psImage* out2 = NULL;
+    psImage* out3 = NULL;
+    psImage* mask = NULL;
+    psImage* meanTruth = NULL;
+    psImage* meanTruthWMask = NULL;
+    psImage* maxTruth = NULL;
+    psStats stats;
+
+    /*
+    Verify the returned psImage structure contains expected values, if the 
+    input parameter input contains known data, the input scale is a known 
+    value with a known statistical method specified in stats. Cases should 
+    include at least two different scales and statistical methods. Comparison 
+    of expected values should include a delta to allow testing on different 
+    platforms.
+    */
+
+    #define testRebinType(DATATYPE)  \
+    in = psImageAlloc(16,16,PS_TYPE_##DATATYPE); \
+    mask = psImageAlloc(16,16,PS_TYPE_U8); \
+    meanTruth = psImageAlloc(4,4,PS_TYPE_F32); \
+    meanTruthWMask = psImageAlloc(4,4,PS_TYPE_F32); \
+    maxTruth = psImageAlloc(6,6,PS_TYPE_F32); \
+    memset(meanTruth->data.F32[0],0,sizeof(psF32)*4*4); \
+    memset(meanTruthWMask->data.F32[0],0,sizeof(psF32)*4*4); \
+    memset(maxTruth->data.F32[0],0,sizeof(psF32)*6*6); \
+    for (int row = 0; row<16; row++) { \
+        ps##DATATYPE* inRow = in->data.DATATYPE[row]; \
+        psF32* meanTruthRow = meanTruth->data.F32[row/4]; \
+        psF32* meanTruthWMaskRow = meanTruthWMask->data.F32[row/4]; \
+        psF32* maxTruthRow = maxTruth->data.F32[row/3]; \
+        psU8* maskRow = mask->data.U8[row]; \
+        for (int col = 0; col<16; col++) { \
+            if(col != 15) { \
+                maskRow[col] = 0; \
+            } else { \
+                maskRow[col] = 1; \
+            } \
+            inRow[col] = row + col; \
+            meanTruthRow[col/4] += row + col; \
+            if (maxTruthRow[col/3] < row + col) { \
+                maxTruthRow[col/3] = row+col; \
+            } \
+            if(maskRow[col] == 0 ) { \
+                meanTruthWMaskRow[col/4] += row + col; \
+            } \
+        } \
+    } \
+    for (int row = 0; row<4; row++) { \
+        psF32* meanTruthRow = meanTruth->data.F32[row]; \
+        psF32* meanTruthWMaskRow = meanTruthWMask->data.F32[row]; \
+        for (int col = 0; col<4; col++) { \
+            meanTruthRow[col] /= 16; \
+            if ( col == 3 ) { \
+                meanTruthWMaskRow[col] /= 12; \
+            } else { \
+                meanTruthWMaskRow[col] /= 16; \
+            } \
+        } \
+    } \
+    stats.options = PS_STAT_SAMPLE_MEAN; \
+    out = psImageRebin(NULL,in,NULL,0,4,&stats); \
+    if (out == NULL) { \
+        psError(__func__,"psImageRebin returned a NULL pointer!?"); \
+        return 1; \
+    } \
+    if (out->numRows != 4 || out->numCols != 4) { \
+        psError(__func__,"psImageRebin didn't produce the proper size image " \
+                "(%d x %d).", \
+                out->numCols, out->numRows); \
+        return 2; \
+    } \
+    for (int row = 0; row<4; row++) { \
+        ps##DATATYPE* outRow = out->data.DATATYPE[row]; \
+        psF32* truthRow = meanTruth->data.F32[row]; \
+        for (int col = 0; col<4; col++) { \
+            if (fabsf((float)outRow[col]-(float)truthRow[col]) > FLT_EPSILON) { \
+                psError(__func__,"psImageRebin didn't produce the proper mean " \
+                        "result at (%d,%d) [%f vs %f].", \
+                        col,row,outRow[col],truthRow[col]); \
+                return 3; \
+            } \
+        } \
+    } \
+    stats.options = PS_STAT_SAMPLE_MEAN; \
+    out3 = psImageRebin(NULL,in,mask,1,4,&stats); \
+    for (int row = 0; row<4; row++) { \
+        ps##DATATYPE* outRow = out3->data.DATATYPE[row]; \
+        psF32* truthRow = meanTruthWMask->data.F32[row]; \
+        for ( int col = 0; col<4; col++) { \
+            if(abs((int)outRow[col]-(int)truthRow[col]) > FLT_EPSILON) { \
+                psError(__func__,"psImageRebin with mask didn't produce the proper mean " \
+                        "result at (%d,%d) [%f vs %f].", \
+                        col,row,outRow[col],truthRow[col]); \
+                return 3; \
+            } \
+        } \
+    } \
+    stats.options = PS_STAT_MAX; \
+    out2 = psImageRebin(out,in,NULL,0,3,&stats); \
+    if (out != out2) { \
+        psError(__func__,"psImageRebin didn't recycle a psImage properly!?"); \
+        return 7; \
+    } \
+    if (out == NULL) { \
+        psError(__func__,"psImageRebin returned a NULL pointer!?"); \
+        return 4; \
+    } \
+    if (out->numRows != 6 || out->numCols != 6) { \
+        psError(__func__,"psImageRebin didn't produce the proper size image " \
+                "(%d x %d).", \
+                out->numCols, out->numRows); \
+        return 5; \
+    } \
+    for (int row = 0; row<6; row++) { \
+        ps##DATATYPE* outRow = out->data.DATATYPE[row]; \
+        psF32* truthRow = maxTruth->data.F32[row]; \
+        for (int col = 0; col<6; col++) { \
+            if (fabsf((float)outRow[col]-(float)truthRow[col]) > FLT_EPSILON) { \
+                psError(__func__,"psImageRebin didn't produce the proper " \
+                        "max result at (%d,%d) [%f vs %f].", \
+                        col,row,outRow[col],truthRow[col]); \
+                return 6; \
+            } \
+        } \
+    } \
+    psFree(in); \
+    psFree(out); \
+    psFree(out3); \
+    psFree(mask); \
+    psFree(meanTruth); \
+    psFree(meanTruthWMask); \
+    psFree(maxTruth);
+
+    testRebinType(F32);
+    testRebinType(F64);
+    testRebinType(U16);
+    testRebinType(S8);
+
+    // Verify the returned psImage structure is null and program execution
+    // doesn't stop, if the input image type is not supported.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for unsupported type.");
+    in = psImageAlloc(16,16,PS_TYPE_U8);
+    mask = psImageAlloc(16,16,PS_TYPE_F32);
+    stats.options = PS_STAT_SAMPLE_MEAN;
+    out = psImageRebin(NULL,in,NULL,0,4,&stats);
+    if(out != NULL) {
+        psError(__func__,"psImageRebin return an image eventhough the "
+                "type is not handled.");
+        return 14;
+    }
+    // Verify the returned psImage structure is null and program execution
+    // doesn't stop, if the mask type is not U8
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for invallid mask type.");
+    out = psImageRebin(NULL,in,mask,1,4,&stats);
+    if(out != NULL) {
+        psError(__func__,"psImageRebin return an image eventhough the "
+                "mask is not the correct type.");
+        return 17;
+    }
+    psFree(mask);
+    psFree(in);
+
+    // Verify the returned psImage structure is null and program execution
+    // doesn't stop, if the input parameter input is null.
+
+    out2 = psImageRebin(NULL,NULL,NULL,0,1,&stats);
+
+    if (out2 != NULL) {
+        psError(__func__,"psImageRebin returned an image though the input was "
+                "NULL!?");
+        return 8;
+    }
+
+    // Verify the returned psImage structure is null and program execution
+    // doesn't stop, if the input parameter scale is less than or equal to zero.
+    in = psImageAlloc(16, 16, PS_TYPE_F32);
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for scale < 0.");
+    out2 = psImageRebin(NULL,in,NULL,0,0,&stats);
+
+    if (out2 != NULL) {
+        psError(__func__,"psImageRebin returned an image though the scale was "
+                "zero!?");
+        return 9;
+    }
+
+    // Verify the returned psImage structure is null and program execution
+    // doesn't stop, if the input parameter stats is null.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for stats null.");
+    out2 = psImageRebin(NULL,in,NULL,0,1,NULL);
+
+    if (out2 != NULL) {
+        psError(__func__,"psImageRebin returned an image though the stats was "
+                "NULL!?");
+        return 10;
+    }
+
+    // Verify the returned psImage structure is null and program execution
+    // doesn't stop, if the input parameter psStats structure member options
+    // is zero or any value which doesn't correspond to a valid statistical
+    // method.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for stats options 0.");
+    stats.options = 0;
+    out2 = psImageRebin(NULL,in,NULL,0,1,&stats);
+
+    if (out2 != NULL) {
+        psError(__func__,"psImageRebin returned an image though the stats "
+                "options was zero!?");
+        return 11;
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for stat options use range.");
+    stats.options = PS_STAT_USE_RANGE;
+    out2 = psImageRebin(NULL,in,NULL,0,1,&stats);
+
+    if (out2 != NULL) {
+        psError(__func__,"psImageRebin returned an image though the stats "
+                "options was PS_STAT_USE_RANGE!?");
+        return 12;
+    }
+
+    // Verify the returned psImage structure is null and program execution
+    // doesn't stop, if the input parameter psStats structure member options
+    // specifies more than one valid statistical method.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for stats with multiple options.");
+    stats.options = PS_STAT_SAMPLE_MEAN + PS_STAT_MAX;
+    out2 = psImageRebin(NULL,in,NULL,0,1,&stats);
+
+    if (out2 != NULL) {
+        psError(__func__,"psImageRebin returned an image though the stats "
+                "options was PS_STAT_SAMPLE_MEAN+PS_STAT_MAX!?");
+        return 13;
+    }
+
+    psFree(in);
+
+    return 0;
+}
+
+static int testImageRoll(void)
+{
+
+    psImage* in;
+    psImage* out;
+    psImage* out2;
+    int rows = 64;
+    int cols = 64;
+    int rows1 = 8;
+    int cols1 = 8;
+
+    /*
+     The function psImageRoll shall generate a new psImage structure by 
+     rolling the input image the correponding number of pixels in the vertical
+     and/or horizontal direction. The image output image shall be the same size
+     as the input image. Values which roll off the image are wrapped to the 
+     other side.
+
+     Verify the returned psImage structure contains expected values, if the 
+     input image contains known values and the roll performed is known. 
+     Cases should include no roll, vertical roll, horizontal roll and 
+     combination vertical/horizontal rolls. Positive and negative rolls 
+     should be performed.
+    */
+
+    in = psImageAlloc(cols,rows,PS_TYPE_F32);
+    for (int row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[row];
+        for (int col=0;col<cols;col++) {
+            inRow[col] = (psF32)row+(psF32)col/1000.0f;
+        }
+    }
+
+    out = psImageRoll(NULL,in,0,0);
+    for (int row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[row];
+        psF32* outRow = out->data.F32[row];
+        for (int col=0;col<cols;col++) {
+            if (inRow[col] != outRow[col]) {
+                psError(__func__,"psImageRoll didn't produce expected result "
+                        "at %d,%d (%f vs %f) for dx=0, dy=0.",
+                        col,row,inRow[col],outRow[col]);
+                return 3;
+            }
+        }
+    }
+
+    out2 = psImageRoll(out,in,cols/4,0);
+    for (int row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[row];
+        psF32* outRow = out->data.F32[row];
+        for (int col=0;col<cols;col++) {
+            if (inRow[(col+cols/4) % cols] != outRow[col]) {
+                psError(__func__,"psImageRoll didn't produce expected result "
+                        "at %d,%d (%f vs %f) for dx=cols/4, dy=0.",
+                        col,row,inRow[(col+cols/4) % cols],outRow[col]);
+                return 4;
+            }
+        }
+    }
+
+    // Verify the returned psImage structure pointer is equal to the input
+    // parameter out if provided.
+    if (out2 != out) {
+        psError(__func__,"psImageRoll didn't recycle my out psImage!?");
+        return 1;
+    }
+
+    out = psImageRoll(out,in,0,rows/4);
+    for (int row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[(row+rows/4)%rows];
+        psF32* outRow = out->data.F32[row];
+        for (int col=0;col<cols;col++) {
+            if (inRow[col] != outRow[col]) {
+                psError(__func__,"psImageRoll didn't produce expected result "
+                        "at %d,%d (%f vs %f) for dx=0, dy=rows/4.",
+                        col,row,inRow[col],outRow[col]);
+                return 5;
+            }
+        }
+    }
+
+    out = psImageRoll(out,in,cols/4,rows/4);
+    for (int row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[(row+rows/4)%rows];
+        psF32* outRow = out->data.F32[row];
+        for (int col=0;col<cols;col++) {
+            if (inRow[(col+cols/4) % cols] != outRow[col]) {
+                psError(__func__,"psImageRoll didn't produce expected result "
+                        "at %d,%d (%f vs %f) for dx=cols/4, dy=rows/4.",
+                        col,row,inRow[(col+cols/4) % cols],outRow[col]);
+                return 6;
+            }
+        }
+    }
+
+    out = psImageRoll(out,in,-cols/4,0);
+    for (int row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[row];
+        psF32* outRow = out->data.F32[row];
+        for (int col=0;col<cols;col++) {
+            if (inRow[(col+(cols-cols/4)) % cols] != outRow[col]) {
+                psError(__func__,"psImageRoll didn't produce expected result "
+                        "at %d,%d (%f vs %f) for dx=-cols/4, dy=0.",
+                        col,row,inRow[(col+(cols-cols/4)) % cols],outRow[col]);
+                return 7;
+            }
+        }
+    }
+
+    out = psImageRoll(out,in,0,-rows/4);
+    for (int row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[(row+rows-rows/4)%rows];
+        psF32* outRow = out->data.F32[row];
+        for (int col=0;col<cols;col++) {
+            if (inRow[col] != outRow[col]) {
+                psError(__func__,"psImageRoll didn't produce expected result "
+                        "at %d,%d (%f vs %f) for dx=0, dy=-rows/4.",
+                        col,row,inRow[col],outRow[col]);
+                return 8;
+            }
+        }
+    }
+
+    out = psImageRoll(out,in,-cols/4,-rows/4);
+    for (int row=0;row<rows;row++) {
+        psF32* inRow = in->data.F32[(row+rows-rows/4)%rows];
+        psF32* outRow = out->data.F32[row];
+        for (int col=0;col<cols;col++) {
+            if (inRow[(col+cols-cols/4) % cols] != outRow[col]) {
+                psError(__func__,"psImageRoll didn't produce expected result "
+                        "at %d,%d (%f vs %f) for dx=cols/4, dy=rows/4.",
+                        col,row,inRow[(col+cols-cols/4) % cols],outRow[col]);
+                return 9;
+            }
+        }
+    }
+
+
+    // Verify the returned psImage structure pointer is null and program
+    // execution doesn't stop, if input parameter input is null.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error.");
+    out2 = psImageRoll(NULL,NULL,0,0);
+    if (out2 != NULL) {
+        psError(__func__,"psImageRoll did not return NULL though input image was NULL!?");
+        return 2;
+    }
+
+    psFree(in);
+    psFree(out);
+
+    #define testRollType(DATATYPE) \
+    in = psImageAlloc(rows1,cols1,PS_TYPE_##DATATYPE); \
+    \
+    for (int row=0;row<rows1;row++) { \
+        ps##DATATYPE* inRow = in->data.DATATYPE[row]; \
+        for (int col=0;col<cols1;col++) { \
+            inRow[col] = (ps##DATATYPE)row+(ps##DATATYPE)col; \
+        } \
+    } \
+    \
+    out = psImageRoll(NULL,in,rows1/4,cols1/4); \
+    for (int row=0;row<rows1;row++) { \
+        ps##DATATYPE* inRow = in->data.DATATYPE[(row+rows1/4)%rows1]; \
+        ps##DATATYPE* outRow = out->data.DATATYPE[row]; \
+        for (int col=0;col<cols1;col++) { \
+            if (inRow[(col+cols1/4)%cols1] != outRow[col]) { \
+                psError(__func__,"psImageRoll didn't produce expected result " \
+                        "at %d,%d (%f vs %f) for dx=0, dy=0.", \
+                        col,row,(float)inRow[col],(float)outRow[col]); \
+                return 3; \
+            } \
+        } \
+    } \
+    psFree(in); \
+    psFree(out);
+
+    testRollType(U8);
+    testRollType(U16);
+    testRollType(S8);
+    testRollType(S16);
+    testRollType(F64);
+    testRollType(C32);
+    testRollType(C64);
+
+    return 0;
+}
+
+int testImageRotate(void)
+{
+    /*
+
+    This function shall calculate a new psImage structure based upon the 
+    rotation of a given psImage structure. The center of rotation shall be the 
+    center pixel of the input image.
+
+    The following steps of the testpoint are done manually via inspection of 
+    temp/fOut.fits & temp/sOut.fits.
+
+        * Verify the returned psImage structure contains expected values, if 
+          the input parameter psImage contains known values. Cases should 
+          include rotations of 0, 45, 90, 135, 180, 225, 270, 315, 360 and at leat one 
+          other arbitrary angle. Cases of the input image should include image
+          with a center pixel and an image without a center pixel.
+        * Verify the returned psImage structure contains pixels set to exposed value, if
+          the rotation and input psImage to not correspond to the output image.
+
+    */
+
+    psImage* fOut = NULL;
+    psImage* sOut = NULL;
+    psImage* s32Out = NULL;
+    psImage* fBiOut = NULL;
+    psImage* sBiOut = NULL;
+    psImage* fTruth = NULL;
+    psImage* sTruth = NULL;
+    psImage* fBiTruth = NULL;
+    psImage* sBiTruth = NULL;
+    int rows = 64;
+    int cols = 64;
+    psImage* fImg = psImageAlloc(cols,rows,PS_TYPE_F32);
+    psImage* sImg = psImageAlloc(cols,rows,PS_TYPE_S16);
+    psImage* s32Img = psImageAlloc(cols,rows,PS_TYPE_S32);
+
+    for(int row=0;row<rows;row++) {
+        psF32* fRow = fImg->data.F32[row];
+        psS16* sRow = sImg->data.S16[row];
+        psS32* s32Row = s32Img->data.S32[row];
+        for (int col=0;col<cols;col++) {
+            fRow[col] = (psF32)(row)+(psF32)(col)/100.0f;
+            sRow[col] = row-2*col;
+            s32Row[col] = row-2*col;
+        }
+    }
+
+    // since interpolation is involved, etc., the simplist way to verify things
+    // is to verify the results manually and bless it for automated comparison
+    // thereafter
+
+
+    // write results of various rotates to a file and verify with truth images
+    mkdir("temp",0777);
+    remove
+        ("temp/fOut.fits")
+        ;
+    remove
+        ("temp/sOut.fits")
+        ;
+    remove
+        ("temp/fBiOut.fits")
+        ;
+    remove
+        ("temp/sBiOut.fits");
+    ;
+    int index = 0;
+    bool fail = false;
+    for (int rot=-180;rot<=180;rot+=45) {
+        psImage* oldOut = fOut;
+        psImage* oldBiOut = fBiOut;
+        fOut = psImageRotate(fOut,fImg,rot,-1.0,PS_INTERPOLATE_FLAT);
+        fBiOut = psImageRotate(fBiOut,fImg,rot,-1.0,PS_INTERPOLATE_BILINEAR);
+        // Verify the returned psImage structure is equal to the input
+        // parameter out if provided.
+        if (oldOut != NULL && oldOut != fOut) {
+            psError(__func__,"the output recycle functionality failed");
+            return 2;
+        }
+        if (oldBiOut != NULL && oldBiOut != fBiOut) {
+            psError(__func__,"the output recycle functionality failed");
+            return 4;
+        }
+        sOut = psImageRotate(sOut,sImg,rot,-1.0,PS_INTERPOLATE_FLAT);
+        sBiOut = psImageRotate(sBiOut,sImg,rot,-1.0,PS_INTERPOLATE_BILINEAR);
+        if (! psImageWriteSection(fOut,0,0,0,NULL,index,"temp/fOut.fits") ) {
+            psError(__func__,"Can not write to temp/fOut.fits, so why continue!?");
+            return 20;
+        }
+        if (! psImageWriteSection(sOut,0,0,0,NULL,index,"temp/sOut.fits") ) {
+            psError(__func__,"Can not write to temp/sOut.fits, so why continue!?");
+            return 21;
+        }
+        if (! psImageWriteSection(fBiOut,0,0,0,NULL,index,"temp/fBiOut.fits") ) {
+            psError(__func__,"Can not write to temp/fBiOut.fits, so why continue!?");
+            return 40;
+        }
+        if (! psImageWriteSection(sBiOut,0,0,0,NULL,index,"temp/sBiOut.fits") ) {
+            psError(__func__,"Can not write to temp/sBiOut.fits, so why continue!?");
+            return 41;
+        }
+
+        // now, let's compare this with the verified file
+        fTruth = psImageReadSection(fTruth,0,0,0,0,0,NULL,index,"verified/fOut.fits");
+        sTruth = psImageReadSection(sTruth,0,0,0,0,0,NULL,index,"verified/sOut.fits");
+        fBiTruth = psImageReadSection(fBiTruth,0,0,0,0,0,NULL,index,"verified/fBiOut.fits");
+        sBiTruth = psImageReadSection(sBiTruth,0,0,0,0,0,NULL,index,"verified/sBiOut.fits");
+        if (fTruth == NULL) {
+            psError(__func__,"verified psF32 image failed to be read (%d deg. rotation)",
+                    rot);
+            fail = true;
+        } else {
+            if (fTruth->numRows != fOut->numRows || fTruth->numCols != fOut->numCols) {
+                psError(__func__,"Rotated float image size did not match truth "
+                        "image for %d deg rotation (%dx%d vs %dx%d).",
+                        rot,fOut->numCols,fOut->numRows,fTruth->numCols,fTruth->numRows);
+                fail = true;
+            } else {
+                for (int row=0;row<fTruth->numRows;row++) {
+                    psF32* truthRow = fTruth->data.F32[row];
+                    psF32* outRow = fOut->data.F32[row];
+                    for (int col=0;col<fTruth->numCols;col++) {
+                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
+                            psError(__func__,"Float Image mismatch (%f vs %f) at %d,%d.",
+                                    outRow[col], truthRow[col],col,row);
+                            fail = true;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (sTruth == NULL) {
+            psError(__func__,"verified psS16 image failed to be read "
+                    "(%d deg. rotation)",rot);
+            fail = true;
+        } else {
+            if (sTruth->numRows != sOut->numRows ||
+                    sTruth->numCols != sOut->numCols) {
+                psError(__func__,"Rotated short image size did not match truth "
+                        "image for %d deg rotation.",rot);
+                fail = true;
+            } else {
+                for (int row=0;row<sTruth->numRows;row++) {
+                    psS16* truthRow = sTruth->data.S16[row];
+                    psS16* outRow = sOut->data.S16[row];
+                    for (int col=0;col<sTruth->numCols;col++) {
+                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
+                            psError(__func__,"Short Image mismatch (%d vs %d) "
+                                    "at %d,%d.",
+                                    outRow[col], truthRow[col],col,row);
+                            fail = true;
+                        }
+                    }
+                }
+            }
+        }
+
+
+        if (fBiTruth == NULL) {
+            psError(__func__,"verified psF32 Bi image failed to be read (%d deg. rotation)",
+                    rot);
+            fail = true;
+        } else {
+            if (fBiTruth->numRows != fBiOut->numRows || fBiTruth->numCols != fBiOut->numCols) {
+                psError(__func__,"Rotated float image size did not match truth "
+                        "image for %d deg rotation (%dx%d vs %dx%d). BILINEAR",
+                        rot,fBiOut->numCols,fBiOut->numRows,fBiTruth->numCols,fBiTruth->numRows);
+                fail = true;
+            } else {
+                for (int row=0;row<fBiTruth->numRows;row++) {
+                    psF32* truthRow = fBiTruth->data.F32[row];
+                    psF32* outRow = fBiOut->data.F32[row];
+                    for (int col=0;col<fBiTruth->numCols;col++) {
+                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
+                            psError(__func__,"Float Image mismatch (%f vs %f) at %d,%d. BILINEAR",
+                                    outRow[col], truthRow[col],col,row);
+                            fail = true;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (sBiTruth == NULL) {
+            psError(__func__,"verified psS16 image failed to be read "
+                    "(%d deg. rotation) BILINEAR",rot);
+            fail = true;
+        } else {
+            if (sBiTruth->numRows != sBiOut->numRows ||
+                    sBiTruth->numCols != sBiOut->numCols) {
+                psError(__func__,"Rotated short image size did not match truth "
+                        "image for %d deg rotation. BILINEAR",rot);
+                fail = true;
+            } else {
+                for (int row=0;row<sBiTruth->numRows;row++) {
+                    psS16* truthRow = sBiTruth->data.S16[row];
+                    psS16* outRow = sBiOut->data.S16[row];
+                    for (int col=0;col<sBiTruth->numCols;col++) {
+                        if (fabsf(truthRow[col]-outRow[col]) > 1) {
+                            psError(__func__,"Short Image mismatch (%d vs %d) "
+                                    "at %d,%d. BILINEAR",
+                                    outRow[col], truthRow[col],col,row);
+                            fail = true;
+                        }
+                    }
+                }
+            }
+        }
+
+        // Verify psImage structure returned is NULL and program execution doesn't stop
+        // if the input image type is not supported. Do not check for 0 degree rotation
+        // since an imgae copy will be used.
+        if (rot != 0 ) {
+            psLogMsg(__func__,PS_LOG_INFO,"Following should be an error invalid type for rotate.");
+            s32Out = psImageRotate(s32Out,s32Img,rot,-1.0,PS_INTERPOLATE_FLAT);
+            if( s32Out != NULL ) {
+                psError(__func__,"psImage returned is not NULL for invalid image type.");
+                return 5;
+            }
+        }
+
+        index++;
+    }
+
+    if (fail) {
+        psError(__func__,"One or more images didn't match truth or truth did "
+                "not exist.");
+        return 10;
+    }
+
+
+    // Verify the returned psImage structure pointer is null and program
+    // execution doesn't stop, if the input parameter input is null.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error");
+    fOut = psImageRotate(fOut,NULL,0,0,PS_INTERPOLATE_FLAT);
+    if (fOut != NULL) {
+        psError(__func__,"NULL wasn't returned though the input image was NULL.");
+        return 3;
+    }
+
+    // Verify the returned psImage structure pointer is null and program
+    // execution doesn't stop, if the specified interpolation mode is invalid
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for invalid "
+             "interpolation type.");
+    fOut = psImageRotate(fOut, fImg, 33, 0, -1);
+    if (fOut != NULL) {
+        psError(__func__,"NULL wasn't returned though the interpolation mode "
+                "is invalid.");
+        return 4;
+    }
+
+    psFree(sOut);
+    psFree(fImg);
+    psFree(sImg);
+    psFree(fTruth);
+    psFree(sTruth);
+    psFree(sBiOut);
+    psFree(fBiTruth);
+    psFree(sBiTruth);
+    psFree(fBiOut);
+    psFree(s32Img);
+    psFree(s32Out);
+
+    return 0;
+}
+
+static int testImageShift(void)
+{
+    /* psImageShift:
+
+       This functions shall generate a new psImage structure by shifting the 
+       input psImage structure a specified number of pixels in the horizontal 
+       and/or vertical directions.
+
+       Verify the returned psImage structure contains expected values, if the 
+       input psImage structure contains known values and a know shift in the 
+       vertical and/or horizontal directions. Cases should include no shift, 
+       vertical only(up,down), horizontal only(right, left), and combination 
+       shift. Cases should include fractional shifts. Comparison of expected 
+       values should include a delta to allow for testing on different 
+       platforms.
+
+       Verify the returned psImage structure contains values for pixels not in 
+       the original image set to the input parameter exposed.
+
+    */
+
+    int retVal=0;
+
+    // integer shift
+    retVal |= testImageShiftCase(64,128,0.0f,0.0f);
+    retVal |= testImageShiftCase(64,128,0.0f,16.0f);
+    retVal |= testImageShiftCase(64,128,0.0f,-16.0f);
+    retVal |= testImageShiftCase(64,128,32.0f,0.0f);
+    retVal |= testImageShiftCase(64,128,-32.0f,0.0f);
+    retVal |= testImageShiftCase(64,128,32.0f,16.0f);
+    retVal |= testImageShiftCase(64,128,32.0f,-16.0f);
+    retVal |= testImageShiftCase(64,128,-32.0f,16.0f);
+    retVal |= testImageShiftCase(64,128,-32.0f,-16.0f);
+
+    if (retVal != 0) {
+        return retVal;
+    }
+
+    // fractional shift
+    retVal |= testImageShiftCase(64,128,0.0f,16.4f);
+    retVal |= testImageShiftCase(64,128,0.0f,-16.4f);
+    retVal |= testImageShiftCase(64,128,32.7f,0.0f);
+    retVal |= testImageShiftCase(64,128,-32.7f,0.0f);
+    retVal |= testImageShiftCase(64,128,32.6f,16.2f);
+    retVal |= testImageShiftCase(64,128,32.6f,-16.2f);
+    retVal |= testImageShiftCase(64,128,-32.6f,16.2f);
+    retVal |= testImageShiftCase(64,128,-32.6f,-16.2f);
+
+    if (retVal != 0) {
+        return retVal;
+    }
+
+    /*
+       Verify the returned psImage structure pointer is equal to the input 
+       parameter out if provided.
+    */
+    psImage* fImg = psImageAlloc(32,32,PS_TYPE_F32);
+    psImage* fRecycle = psImageAlloc(32,32,PS_TYPE_F32);
+    psImage* fOut = psImageShift(fRecycle, fImg, 8,8, NAN, PS_INTERPOLATE_FLAT);
+
+    if (fRecycle != fOut) {
+        psError(__func__,"psImageShift didn't recycle my image?");
+        return 10;
+    }
+
+    /*
+       Verify the returned psImage structure pointer is null and program 
+       execution doesn't stop, if the input psImage structure pointer is null.
+    */
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error...");
+    fOut = psImageShift(fOut,NULL,8,8,NAN,PS_INTERPOLATE_FLAT);
+    if (fOut != NULL) {
+        psError(__func__,"psImageShift didn't return NULL given a NULL input image.");
+        return 11;
+    }
+
+    // Verify the returned psImage structure is null and program execution
+    // doesn't stop, if the specified interpolation mode is invalid.
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for invalid interpolation mode.");
+    fOut = psImageShift(fOut,fImg,8,8,NAN,-1);
+    if (fOut != NULL ) {
+        psError(__func__,"psImageShift didn't return NULL given an invalid interpolation mode.");
+        return 12;
+    }
+
+    psFree(fImg);
+
+    return 0;
+}
+
+static int testImageShiftCase(int cols,
+                              int rows,
+                              float colShift,
+                              float rowShift)
+{
+    psImage* fOut = NULL;
+    psImage* sOut = NULL;
+
+    psLogMsg(__func__,PS_LOG_INFO,"Testing psImageShift with a %dx%d image for "
+             "a shift of %g,%g.",cols,rows,colShift,rowShift);
+
+    psImage* fImg = psImageAlloc(cols,rows,PS_TYPE_F32);
+    psImage* sImg = psImageAlloc(cols,rows,PS_TYPE_S16);
+    psImage* fBiOut = psImageAlloc(cols,rows,PS_TYPE_F32);
+    psImage* sBiOut = psImageAlloc(cols,rows,PS_TYPE_S16);
+
+    for(int row=0;row<rows;row++) {
+        psF32* fRow = fImg->data.F32[row];
+        psS16* sRow = sImg->data.S16[row];
+        for (int col=0;col<cols;col++) {
+            fRow[col] = (psF32)(row)+(psF32)(col)/100.0f;
+            sRow[col] = row-2*col;
+        }
+    }
+
+    fOut = psImageShift(fOut, fImg, colShift, rowShift, NAN, PS_INTERPOLATE_FLAT);
+    sOut = psImageShift(sOut, sImg, colShift, rowShift, -1, PS_INTERPOLATE_FLAT);
+    fBiOut = psImageShift(fBiOut, fImg, colShift, rowShift, NAN, PS_INTERPOLATE_BILINEAR);
+    sBiOut = psImageShift(sBiOut, sImg, colShift, rowShift, -1, PS_INTERPOLATE_BILINEAR);
+
+    for(int row=0;row<rows;row++) {
+        psF32* fRow = fOut->data.F32[row];
+        psS16* sRow = sOut->data.S16[row];
+        psF32* fBiRow = fBiOut->data.F32[row];
+        psS16* sBiRow = sBiOut->data.S16[row];
+
+        for (int col=0;col<cols;col++) {
+            psF32 fValue = psImagePixelInterpolate(fImg,col+colShift,
+                                                   row+rowShift,NULL,0,NAN,PS_INTERPOLATE_FLAT);
+            psS16 sValue = (psS16)psImagePixelInterpolate(sImg,col+colShift,
+                           row+rowShift,NULL,0,-1,PS_INTERPOLATE_FLAT);
+
+            psF32 fBiValue = psImagePixelInterpolate(fImg,col+colShift,
+                             row+rowShift,NULL,0,NAN,PS_INTERPOLATE_BILINEAR);
+            psS16 sBiValue = (psS16)psImagePixelInterpolate(sImg,col+colShift,
+                             row+rowShift,NULL,0,-1,PS_INTERPOLATE_BILINEAR);
+
+            if (fabsf(fRow[col] - fValue) > FLT_EPSILON) {
+                psError(__func__,"Float image not shifted correctly at %d,%d (%g vs %g)",
+                        col,row,fRow[col],fValue);
+                return 1;
+            }
+            if (sRow[col] != sValue) {
+                psError(__func__,"Short image not shifted correctly at %d,%d (%d vs %d)",
+                        col,row,sRow[col],sValue);
+                return 2;
+            }
+            if (fabsf(fBiRow[col] - fBiValue) > FLT_EPSILON) {
+                psError(__func__,"Float image not shifted correctly at %d,%d (%g vs %g)",
+                        col,row,fBiRow[col],fBiValue);
+                return 1;
+            }
+            if (sBiRow[col] != sBiValue) {
+                psError(__func__,"Short image not shifted correctly at %d,%d (%d vs %d)",
+                        col,row,sBiRow[col],sBiValue);
+                return 2;
+            }
+        }
+    }
+
+    psFree(fImg);
+    psFree(sImg);
+    psFree(fOut);
+    psFree(sOut);
+    psFree(fBiOut);
+    psFree(sBiOut);
+
+    return 0;
+}
+
+static int testImageResample(void)
+{
+
+    int rows = 60;
+    int cols = 80;
+    psImage* result = NULL;
+    int scale = 4;
+    psErr* err;
+
+    psImage* image = psImageAlloc(cols,rows,PS_TYPE_F32);
+    for(int row=0;row<rows;row++) {
+        psF32* imageRow = image->data.F32[row];
+        for (int col=0;col<cols;col++) {
+            imageRow[col] = row+2*col;
+        }
+    }
+    result = psImageCopy(NULL,image,PS_TYPE_F64);
+    psImage* orig = result;
+    result = psImageResample(result,image,scale,PS_INTERPOLATE_FLAT);
+
+    if (result == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "NULL return unexpected");
+        return 1;
+    }
+
+    if (result != orig) {
+        psLogMsg(__func__,PS_LOG_ERROR,"failure to recycle image.");
+        return 2;
+    }
+
+    if (result->type.type != PS_TYPE_F32) {
+        psLogMsg(__func__,PS_LOG_ERROR,"unexpected type");
+        return 3;
+    }
+
+
+    if (result->numCols != image->numCols*scale ||
+            result->numRows != image->numRows*scale) {
+        psLogMsg(__func__,PS_LOG_ERROR,"The size of the result is %dx%d, but %dx%d was expected.",
+                 result->numCols,result->numRows,
+                 image->numCols*scale, image->numRows*scale);
+        return 4;
+    }
+
+    psF32 truthValue;
+    for(int row=0;row<result->numRows;row++) {
+        for (int col=0;col<result->numCols;col++) {
+            truthValue = psImagePixelInterpolate(image,
+                                                 (float)col/(float)scale,(float)row/(float)scale,
+                                                 NULL,0,-1,PS_INTERPOLATE_FLAT);
+            if (fabs(truthValue - result->data.F32[row][col]) > FLT_EPSILON) {
+                psLogMsg(__func__,PS_LOG_ERROR,"value bad at (%d,%d).  Got %g, expected %g.",
+                         col,row,result->data.F32[row][col], truthValue);
+                return 5;
+            }
+        }
+    }
+
+    // verify that image=null is handled properly.
+    psErrorClear();
+    result = psImageResample(result,NULL,scale,PS_INTERPOLATE_FLAT);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "return was not NULL, as expected.");
+        return 6;
+    }
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "error message was not appropriate type.");
+        return 7;
+    }
+    psFree(err);
+
+    // verify that scale < 1 is handled properly
+    psErrorClear();
+    result = psImageResample(result,image,0,PS_INTERPOLATE_FLAT);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "return was not NULL, as expected.");
+        return 8;
+    }
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "error message was not appropriate type.");
+        return 9;
+    }
+    psFree(err);
+
+    // verify that invalid interpolation mode is handled properly
+    psErrorClear();
+    result = psImageResample(result,image,2,0);
+
+    if (result != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "return was not NULL, as expected.");
+        return 10;
+    }
+    err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_VALUE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "error message was not appropriate type.");
+        return 11;
+    }
+    psFree(err);
+
+    psFree(image);
+    psFree(result);
+
+    return 0;
+}
+
Index: /branches/rel3/psLib/test/image/tst_psImageStats00.c
===================================================================
--- /branches/rel3/psLib/test/image/tst_psImageStats00.c	(revision 2163)
+++ /branches/rel3/psLib/test/image/tst_psImageStats00.c	(revision 2163)
@@ -0,0 +1,203 @@
+/*****************************************************************************
+   This routine must ensure that the psHistogram structure is correctly
+   allocated and populated by the psImageHistogram() function.
+*****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psImage.h"
+#include "psImageStats.h"
+#define NUM_BINS 20
+#define IMAGE_SIZE 20
+#define N 32
+#define M 64
+
+int main()
+{
+    psHistogram * myHist = NULL;
+    psHistogram *myHist2 = NULL;
+    psImage *tmpImage = NULL;
+    psImage *tmpMask = NULL;
+    int testStatus = true;
+    int memLeaks = 0;
+    int nb = 0;
+    int i = 0;
+    int j = 0;
+    int IMAGE_X_SIZE = 0;
+    int IMAGE_Y_SIZE = 0;
+    int currentId = 0;
+
+    currentId = psMemGetId();
+    for ( nb = 0;nb < 6;nb++ ) {
+        if ( nb == 0 ) {
+            IMAGE_X_SIZE = 1;
+            IMAGE_Y_SIZE = 1;
+        }
+        if ( nb == 1 ) {
+            IMAGE_X_SIZE = 1;
+            IMAGE_Y_SIZE = N;
+        }
+        if ( nb == 2 ) {
+            IMAGE_X_SIZE = N;
+            IMAGE_Y_SIZE = 1;
+        }
+        if ( nb == 3 ) {
+            IMAGE_X_SIZE = N;
+            IMAGE_Y_SIZE = N;
+        }
+        if ( nb == 4 ) {
+            IMAGE_X_SIZE = N;
+            IMAGE_Y_SIZE = M;
+        }
+        if ( nb == 5 ) {
+            IMAGE_X_SIZE = M;
+            IMAGE_Y_SIZE = N;
+        }
+        printf( "*******************************\n" );
+        printf( "* IMAGE SIZE is (%d by %d)\n", IMAGE_X_SIZE, IMAGE_Y_SIZE );
+        printf( "*******************************\n" );
+        /*********************************************************************/
+        /*  Allocate and initialize data structures                      */
+        /*********************************************************************/
+        tmpImage = psImageAlloc( IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_F32 );
+
+        for ( i = 0;i < tmpImage->numRows;i++ ) {
+            for ( j = 0;j < tmpImage->numCols;j++ ) {
+                tmpImage->data.F32[ i ][ j ] = ( float ) ( i + j + 0.1 );
+            }
+        }
+        tmpMask = psImageAlloc( IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_U8 );
+        for ( i = 0;i < tmpMask->numRows;i++ ) {
+            for ( j = 0;j < tmpMask->numCols;j++ ) {
+                if ( ( i > ( tmpMask->numRows / 2 ) ) &&
+                        ( j > ( tmpMask->numCols / 2 ) ) ) {
+                    tmpMask->data.U8[ i ][ j ] = 1;
+                } else {
+                    tmpMask->data.U8[ i ][ j ] = 0;
+                }
+            }
+        }
+
+        /*************************************************************************/
+        /*  Calculate Histogram with no mask                             */
+        /*************************************************************************/
+        printPositiveTestHeader( stdout,
+                                 "psImageStats functions",
+                                 "Calculate Histogram, no mask" );
+
+        myHist = psHistogramAlloc( 0.0, ( float ) ( IMAGE_X_SIZE + IMAGE_Y_SIZE ),
+                                   NUM_BINS );
+        myHist = psImageHistogram( myHist, tmpImage, NULL, 0 );
+        for ( i = 0;i < NUM_BINS;i++ ) {
+            printf( "Bin number %d bounds: (%.1f - %.1f) data (%d)\n", i,
+                    myHist->bounds->data.F32[ i ],
+                    myHist->bounds->data.F32[ i + 1 ],
+                    myHist->nums->data.S32[ i ] );
+        }
+        psFree( myHist );
+
+        psMemCheckCorruption( 1 );
+        printFooter( stdout,
+                     "psImageStats functions",
+                     "Calculate Histogram, no mask",
+                     testStatus );
+
+        /*************************************************************************/
+        /*  Calculate Histogram with mask                                */
+        /*************************************************************************/
+        printPositiveTestHeader( stdout,
+                                 "psImageStats functions",
+                                 "Calculate Histogram with mask" );
+
+        myHist = psHistogramAlloc( 0.0, ( float ) ( IMAGE_X_SIZE + IMAGE_Y_SIZE ),
+                                   NUM_BINS );
+        myHist = psImageHistogram( myHist, tmpImage, tmpMask, 1 );
+        for ( i = 0;i < NUM_BINS;i++ ) {
+            printf( "Bin number %d bounds: (%.2f - %.2f) data (%d)\n", i,
+                    myHist->bounds->data.F32[ i ],
+                    myHist->bounds->data.F32[ i + 1 ],
+                    myHist->nums->data.S32[ i ] );
+        }
+
+        psMemCheckCorruption( 1 );
+        printFooter( stdout,
+                     "psImageStats functions",
+                     "Calculate Histogram with mask",
+                     testStatus );
+
+        /*************************************************************************/
+        /*  Deallocate data structures                                   */
+        /*************************************************************************/
+        printPositiveTestHeader( stdout,
+                                 "psImageStats functions",
+                                 "Deallocate the psHistogram/psImage structure." );
+        psFree( myHist );
+        psFree( tmpImage );
+        psFree( tmpMask );
+
+        psMemCheckCorruption( 1 );
+        memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+        if ( 0 != memLeaks ) {
+            psAbort( __func__, "Memory Leaks! (%d leaks)", memLeaks );
+        }
+
+        printFooter( stdout,
+                     "psImageStats functions",
+                     "Deallocate the psHistogram/psImage structure.",
+                     testStatus );
+    }
+    printPositiveTestHeader( stdout,
+                             "psImageStats functions",
+                             "Calling psImageHistogram() with NULL parameters" );
+
+    tmpImage = psImageAlloc( IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_F32 );
+    myHist = psHistogramAlloc( 0.0, ( float ) ( IMAGE_X_SIZE + IMAGE_Y_SIZE ),
+                               NUM_BINS );
+    myHist2 = psImageHistogram( NULL, tmpImage, NULL, 0 );
+    if ( myHist2 != NULL ) {
+        printf( "ERROR: myHist2 not equal to NULL\n" );
+    }
+
+    myHist2 = psImageHistogram( myHist, NULL, NULL, 0 );
+    myHist2 = psImageHistogram( NULL, tmpImage, NULL, 0 );
+    if ( myHist2 != NULL ) {
+        printf( "ERROR: myHist2 not equal to NULL\n" );
+    }
+
+
+    tmpMask = psImageAlloc( IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_S8 );
+    for ( i = 0;i < tmpMask->numRows;i++ ) {
+        for ( j = 0;j < tmpMask->numCols;j++ ) {
+            if ( ( i > ( tmpMask->numRows / 2 ) ) &&
+                    ( j > ( tmpMask->numCols / 2 ) ) ) {
+                tmpMask->data.S8[ i ][ j ] = 1;
+            } else {
+                tmpMask->data.S8[ i ][ j ] = 0;
+            }
+        }
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error for invalid mask type.");
+    myHist2 = psImageHistogram(myHist,tmpImage,tmpMask,1);
+    if (myHist2 != NULL) {
+        printf("ERROR: myHist2 not equal to NULL\n");
+    }
+
+    psFree( tmpMask );
+
+    psMemCheckCorruption( 1 );
+    psFree( tmpImage );
+    psMemCheckCorruption( 1 );
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if ( 0 != memLeaks ) {
+        psAbort( __func__, "Memory Leaks! (%d leaks)", memLeaks );
+    }
+
+    printFooter( stdout,
+                 "psImageStats functions",
+                 "Calling psImageHistogram() with NULL parameters",
+                 testStatus );
+
+    return ( !testStatus );
+}
Index: /branches/rel3/psLib/test/image/tst_psImageStats01.c
===================================================================
--- /branches/rel3/psLib/test/image/tst_psImageStats01.c	(revision 2163)
+++ /branches/rel3/psLib/test/image/tst_psImageStats01.c	(revision 2163)
@@ -0,0 +1,199 @@
+/*****************************************************************************
+   This routine must ensure that the psImageStats() routine can correctly
+   call the psVectorStats() routine.  Since the psVectorStats() will be
+   thouroughly tested elsewhere, we will only test psImageStats() with
+   the PS_STAT_SAMPLE_MEAN here.
+*****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psImage.h"
+#include "psImageStats.h"
+#define NUM_BINS 20
+#define N 32
+#define M 64
+
+int main()
+{
+    psStats * myStats = NULL;
+    psStats *myStats2 = NULL;
+    psImage *tmpImage = NULL;
+    psImage *tmpMask = NULL;
+    int testStatus = true;
+    int memLeaks = 0;
+    int nb = 0;
+    int i = 0;
+    int j = 0;
+    int IMAGE_X_SIZE = 0;
+    int IMAGE_Y_SIZE = 0;
+    int currentId = 0;
+
+    currentId = psMemGetId();
+    for ( nb = 0;nb < 6;nb++ ) {
+        if ( nb == 0 ) {
+            IMAGE_X_SIZE = 1;
+            IMAGE_Y_SIZE = 1;
+        }
+        if ( nb == 1 ) {
+            IMAGE_X_SIZE = 1;
+            IMAGE_Y_SIZE = N;
+        }
+        if ( nb == 2 ) {
+            IMAGE_X_SIZE = N;
+            IMAGE_Y_SIZE = 1;
+        }
+        if ( nb == 3 ) {
+            IMAGE_X_SIZE = N;
+            IMAGE_Y_SIZE = N;
+        }
+        if ( nb == 4 ) {
+            IMAGE_X_SIZE = N;
+            IMAGE_Y_SIZE = M;
+        }
+        if ( nb == 5 ) {
+            IMAGE_X_SIZE = M;
+            IMAGE_Y_SIZE = N;
+        }
+        printf( "*******************************\n" );
+        printf( "* IMAGE SIZE is (%d by %d)\n", IMAGE_X_SIZE, IMAGE_Y_SIZE );
+        printf( "*******************************\n" );
+
+        /*************************************************************************/
+        /*  Allocate and initialize data structures                      */
+        /*************************************************************************/
+        tmpImage = psImageAlloc( IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_F32 );
+
+        for ( i = 0;i < tmpImage->numRows;i++ ) {
+            for ( j = 0;j < tmpImage->numCols;j++ ) {
+                tmpImage->data.F32[ i ][ j ] = ( float ) ( i + j );
+            }
+        }
+        tmpMask = psImageAlloc( IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_U8 );
+        for ( i = 0;i < tmpMask->numRows;i++ ) {
+            for ( j = 0;j < tmpMask->numCols;j++ ) {
+                if ( ( i > ( tmpMask->numRows / 2 ) ) &&
+                        ( j > ( tmpMask->numCols / 2 ) ) ) {
+                    tmpMask->data.U8[ i ][ j ] = 1;
+                } else {
+                    tmpMask->data.U8[ i ][ j ] = 0;
+                }
+            }
+        }
+
+        myStats = psStatsAlloc( PS_STAT_SAMPLE_MEAN );
+        /*************************************************************************/
+        /*  Calculate Sample Mean with no mask                           */
+        /*************************************************************************/
+        printPositiveTestHeader( stdout,
+                                 "psImageStats functions",
+                                 "Calculate Sample Mean, no mask %d" );
+        psStats* tmpStats = myStats;
+        myStats = psImageStats( myStats, tmpImage, NULL, 0 );
+        if ( myStats != tmpStats ) {
+            printf("ERROR: input psStats not equal to return psStats\n");
+            psAbort(__func__,"Failed input psStats equal to returned psStats");
+        }
+        printf( "The sample mean was %.2f\n", myStats->sampleMean );
+
+        psMemCheckCorruption( 1 );
+
+        printFooter( stdout,
+                     "psImageStats functions",
+                     "Calculate Sample Mean, no mask",
+                     testStatus );
+
+        /*************************************************************************/
+        /*  Calculate Sample Mean with mask                              */
+        /*************************************************************************/
+        printPositiveTestHeader( stdout,
+                                 "psImageStats functions",
+                                 "Calculate Sample Mean with mask" );
+
+        myStats = psImageStats( myStats, tmpImage, tmpMask, 1 );
+        printf( "The sample mean was %.2f\n", myStats->sampleMean );
+
+        psMemCheckCorruption( 1 );
+
+        printFooter( stdout,
+                     "psImageStats functions",
+                     "Calculate Sample Mean with mask",
+                     testStatus );
+
+        /*************************************************************************/
+        /*  Deallocate data structures                                   */
+        /*************************************************************************/
+        printPositiveTestHeader( stdout,
+                                 "psImageStats functions",
+                                 "Deallocate the psStats/psImage structure." );
+        psFree( myStats );
+        psFree( tmpImage );
+        psFree( tmpMask );
+
+        psMemCheckCorruption( 1 );
+        memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+        if ( 0 != memLeaks ) {
+            psAbort( __func__, "Memory Leaks! (%d leaks)", memLeaks );
+        }
+
+        printFooter( stdout,
+                     "psImageStats functions",
+                     "Deallocate the psStats/psImage structure.",
+                     testStatus );
+    }
+
+    /*************************************************************************/
+    /*  Test With Various Null Inputs                                        */
+    /*************************************************************************/
+    printPositiveTestHeader( stdout,
+                             "psImageStats functions",
+                             "Test With Various Null Inputs" );
+
+    tmpImage = psImageAlloc( IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_F32 );
+    tmpMask = psImageAlloc( IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_U8 );
+    myStats = psStatsAlloc( 0 );
+
+    myStats2 = psImageStats( myStats, NULL, NULL, 0 );
+    if ( myStats2 != NULL ) {
+        printf( "ERROR: myStats2 = psImageStats(myStats, NULL, NULL, 0) != NULL\n" );
+    }
+
+    myStats2 = psImageStats( NULL, tmpImage, NULL, 0 );
+    if ( myStats2 != NULL ) {
+        printf( "ERROR: myStats2 = psImageStats(NULL, tmpImage, NULL, 0) != NULL\n" );
+    }
+
+    myStats2 = psImageStats( myStats, tmpImage, NULL, 0 );
+
+    psFree( myStats );
+    psFree( tmpImage );
+    psFree( tmpMask );
+
+    psMemCheckCorruption( 1 );
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if ( 0 != memLeaks ) {
+        psAbort( __func__, "Memory Leaks! (%d leaks)", memLeaks );
+    }
+
+    tmpImage = psImageAlloc( IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_F32);
+    tmpMask = psImageAlloc( IMAGE_X_SIZE, IMAGE_Y_SIZE, PS_TYPE_U32);
+    myStats = psStatsAlloc( PS_STAT_SAMPLE_MEAN );
+    myStats2 = psImageStats( myStats, tmpImage, tmpMask, 0 );
+    if ( myStats2 != NULL ) {
+        printf( "ERROR: psImageStats did not return null when mask is invalid type.\n");
+    }
+    psFree(tmpImage);
+    psFree(tmpMask);
+    psFree(myStats);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if( memLeaks != 0 ) {
+        psAbort(__func__, "Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    printFooter( stdout,
+                 "psImageStats functions",
+                 "Test With Various Null Inputs",
+                 testStatus );
+    return ( !testStatus );
+}
Index: /branches/rel3/psLib/test/image/tst_psImageStats02.c
===================================================================
--- /branches/rel3/psLib/test/image/tst_psImageStats02.c	(revision 2163)
+++ /branches/rel3/psLib/test/image/tst_psImageStats02.c	(revision 2163)
@@ -0,0 +1,146 @@
+/*****************************************************************************
+   This routine must ensure that the psImageFitPolynomial() and
+   psImageEvalPolynomial() rotines work correctly.
+ 
+   XXX: After you debug, set CHEBY_X_DIM != CHEBY_Y_DIM.
+   XXX: use non-square images.
+*****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psImage.h"
+#include "psImageStats.h"
+#include <float.h>
+#include <math.h>
+#define IMAGE_SIZE 64
+#define CHEBY_X_DIM 8
+#define CHEBY_Y_DIM 8
+#define THRESHOLD 10
+int main()
+{
+    psStats * myStats = NULL;
+    psImage *tmpImage = NULL;
+    psImage *outImage = NULL;
+    psImage *nullImage = NULL;
+    psPolynomial2D *my2DPoly = NULL;
+    psPolynomial2D *null2DPoly = NULL;
+    int testStatus = true;
+    int memLeaks = 0;
+    int i = 0;
+    int j = 0;
+    int currentId = 0;
+
+    currentId = psMemGetId();
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    tmpImage = psImageAlloc( IMAGE_SIZE, IMAGE_SIZE, PS_TYPE_F32 );
+    outImage = psImageAlloc( IMAGE_SIZE, IMAGE_SIZE, PS_TYPE_F32 );
+    for ( i = 0;i < IMAGE_SIZE;i++ ) {
+        for ( j = 0;j < IMAGE_SIZE;j++ ) {
+            tmpImage->data.F32[ i ][ j ] = 4.0;
+            tmpImage->data.F32[ i ][ j ] = ( float ) ( i + j );
+            tmpImage->data.F32[ i ][ j ] = ( float ) ( i + j ) + ( 4.0 * ( float ) i );
+            outImage->data.F32[ i ][ j ] = 0.0;
+        }
+    }
+    my2DPoly = psPolynomial2DAlloc( CHEBY_X_DIM, CHEBY_Y_DIM, PS_POLYNOMIAL_CHEB );
+    /*************************************************************************/
+    /*  Calculate Chebyshev Polynomials, no mask                     */
+    /*************************************************************************/
+    printPositiveTestHeader( stdout,
+                             "psImageStats functions",
+                             "Calculate Chebyshev Polynomials, no mask" );
+
+    my2DPoly = psImageFitPolynomial( my2DPoly, tmpImage );
+    for ( i = 0;i < CHEBY_X_DIM;i++ ) {
+        for ( j = 0;j < CHEBY_Y_DIM;j++ ) {
+            printf( "Cheby Polynomial (%d, %d) coefficient is %.2f\n", i, j, 0.0001f+my2DPoly->coeff[ i ][ j ] );
+        }
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error message for NULL coeffs argument.");
+    null2DPoly = psImageFitPolynomial( NULL, tmpImage );
+    if ( null2DPoly != NULL ) {
+        printf("ERROR: psImageFitPolynomial did not return NULL with invalid coeffs argument.");
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be a error message for NULL input argument.");
+    null2DPoly = psImageFitPolynomial( null2DPoly, NULL );
+    if ( null2DPoly != NULL ) {
+        printf("ERROR: psImageFitPolynomial did not return NULL with null input image.");
+    }
+
+    psMemCheckCorruption( 1 );
+    printFooter( stdout,
+                 "psImageStats functions",
+                 "Calculate Chebyshev Polynomials, no mask",
+                 testStatus );
+    /*************************************************************************/
+    /*  Evaluate Chebyshev Polynomials, no mask                      */
+    /*************************************************************************/
+    printPositiveTestHeader( stdout,
+                             "psImageStats functions",
+                             "Calculate Chebyshev Polynomials, no mask" );
+
+    outImage = psImageEvalPolynomial( outImage, my2DPoly );
+    for ( i = 0;i < IMAGE_SIZE;i++ ) {
+        for ( j = 0;j < IMAGE_SIZE;j++ ) {
+
+            //             printf("pixel[%d][%d] is (%f, %f)\n", i, j,
+            //                     tmpImage->data.F32[i][j],
+            //                     outImage->data.F32[i][j]);
+            if ( fabs( outImage->data.F32[ i ][ j ] - tmpImage->data.F32[ i ][ j ] ) > THRESHOLD ) {
+                printf( "Pixel (%d, %d) is %.2f, should be %.2f\n", i, j,
+                        outImage->data.F32[ i ][ j ],
+                        tmpImage->data.F32[ i ][ j ] );
+            }
+
+        }
+    }
+
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error message for NULL coeffs argument.");
+    nullImage = psImageEvalPolynomial( outImage, NULL );
+    if ( nullImage != NULL ) {
+        printf("ERROR: psImageEvalPolynomial did not return NULL with invalid coeffs argument.");
+    }
+
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be a error message for NULL input argument.");
+    nullImage = psImageEvalPolynomial( NULL, my2DPoly );
+    if ( nullImage != NULL ) {
+        printf("ERROR: psImageEvalPolynomial did not return NULL with null input image.");
+    }
+
+
+    psMemCheckCorruption( 1 );
+    printFooter( stdout,
+                 "psImageStats functions",
+                 "Calculate Chebyshev Polynomials, no mask",
+                 testStatus );
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    printPositiveTestHeader( stdout,
+                             "psImageStats functions",
+                             "Deallocate the psStats/psImage structure." );
+    psFree( myStats );
+    psFree( tmpImage );
+    psFree( outImage );
+    psFree( my2DPoly );
+
+    psMemCheckCorruption( 1 );
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if ( 0 != memLeaks ) {
+        psAbort( __func__, "Memory Leaks! (%d leaks)", memLeaks );
+    }
+
+    printFooter( stdout,
+                 "psImageStats functions",
+                 "Deallocate the psStats/psImage structure.",
+                 testStatus );
+
+    return ( !testStatus );
+}
Index: /branches/rel3/psLib/test/image/tst_psImageStats03.c
===================================================================
--- /branches/rel3/psLib/test/image/tst_psImageStats03.c	(revision 2163)
+++ /branches/rel3/psLib/test/image/tst_psImageStats03.c	(revision 2163)
@@ -0,0 +1,92 @@
+/*****************************************************************************
+    This routine must ensure that the psImagePixelInterpolation() routine
+    works correctly.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+#include "psMemory.h"
+#include "psImage.h"
+#include "psImageStats.h"
+#include <float.h>
+#include <math.h>
+#define IMAGE_SIZE 10
+
+int main()
+{
+    psImage *tmpImage   = NULL;
+    int testStatus      = true;
+    int memLeaks        = 0;
+    int i               = 0;
+    int j               = 0;
+    float pixel         = 0.0;
+    float x             = 0.0;
+    float y             = 0.0;
+    int currentId       = psMemGetId();
+
+    /*************************************************************************/
+    /*  Allocate and initialize data structures                      */
+    /*************************************************************************/
+    printPositiveTestHeader(stdout,
+                            "psImageStats functions",
+                            "psImagePixelInterpolation()");
+
+    tmpImage = psImageAlloc(IMAGE_SIZE, IMAGE_SIZE, PS_TYPE_F32);
+    for (i=0;i<IMAGE_SIZE;i++) {
+        for (j=0;j<IMAGE_SIZE;j++) {
+            tmpImage->data.F32[i][j] = 4.0;
+            tmpImage->data.F32[i][j] = (float) (i + j) + (4.0 * (float) i);
+            tmpImage->data.F32[i][j] = (float) (i + j);
+            printf("%.1f ", tmpImage->data.F32[i][j]);
+        }
+        printf("\n");
+    }
+    for (i=0;i<IMAGE_SIZE-1;i++) {
+        for (j=0;j<IMAGE_SIZE-1;j++) {
+            x = 0.2 + (float) i;
+            y = 0.2 + (float) j;
+            pixel = psImagePixelInterpolate(tmpImage,
+                                            x, y,
+                                            NULL, 0,
+                                            0,
+                                            PS_INTERPOLATE_BILINEAR);
+            printf("%.1f ", pixel);
+        }
+        printf("\n");
+    }
+
+    for (i=0;i<IMAGE_SIZE-1;i++) {
+        for (j=0;j<IMAGE_SIZE-1;j++) {
+            x = 0.2 + (float) i;
+            y = 0.2 + (float) j;
+            pixel = psImagePixelInterpolate(tmpImage,
+                                            x, y,
+                                            NULL,0,
+                                            0,
+                                            PS_INTERPOLATE_BILINEAR);
+            printf("image[%.1f][%.1f] is interpolated at %.1f\n", x, y, pixel);
+        }
+    }
+
+
+    psFree(tmpImage);
+    psMemCheckCorruption(1);
+    printFooter(stdout,
+                "psImageStats functions",
+                "psImagePixelInterpolation()",
+                testStatus);
+
+    /*************************************************************************/
+    /*  Deallocate data structures                                   */
+    /*************************************************************************/
+    // GUS: replace with psFree()?
+    //    psImageFree(tmpImage);
+
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    return (!testStatus);
+}
Index: /branches/rel3/psLib/test/image/verified/fBiOut.fits
===================================================================
--- /branches/rel3/psLib/test/image/verified/fBiOut.fits	(revision 2163)
+++ /branches/rel3/psLib/test/image/verified/fBiOut.fits	(revision 2163)
@@ -0,0 +1,6427 @@
+SIMPLE  =                    T / file does conform to FITS standard             BITPIX  =                  -32 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   64 / length of data axis 1                          NAXIS2  =                   64 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          EXTEND  =                    T / FITS dataset may contain extensions            COMMENT   FITS (Flexible Image Transport System) format is defined in 'AstronomyCOMMENT   and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             B~
+B~záB~p€B~ffB~\)B~QìB~G®B~=qB~33B~(öB~
+žB~{B~
+=B~  B}õÃB}ë
+B}áHB}×
+B}ÌÍB}ÂB}žRB}®B}£×B}B}\B}
+B}záB}p€B}ffB}\)B}QìB}G®B}=qB}33B}(öB}
+žB}{B}
+=B}  B|õÃB|ë
+B|áHB|×
+B|ÌÍB|ÂB|žRB|®B|£×B|B|\B|
+B|záB|p€B|ffB|\)B|QìB|G®B|=qB|33B|(öB|
+žB|{B|
+=B|  Bz
+BzzáBzp€BzffBz\)BzQìBzG®Bz=qBz33Bz(öBz
+žBz{Bz
+=Bz  ByõÃByë
+ByáHBy×
+ByÌÍByÂByžRBy®By£×ByBy\By
+ByzáByp€ByffBy\)ByQìByG®By=qBy33By(öBy
+žBy{By
+=By  BxõÃBxë
+BxáHBx×
+BxÌÍBxÂBxžRBx®Bx£×BxBx\Bx
+BxzáBxp€BxffBx\)BxQìBxG®Bx=qBx33Bx(öBx
+žBx{Bx
+=Bx  Bv
+BvzáBvp€BvffBv\)BvQìBvG®Bv=qBv33Bv(öBv
+žBv{Bv
+=Bv  BuõÃBuë
+BuáHBu×
+BuÌÍBuÂBužRBu®Bu£×BuBu\Bu
+BuzáBup€BuffBu\)BuQìBuG®Bu=qBu33Bu(öBu
+žBu{Bu
+=Bu  BtõÃBtë
+BtáHBt×
+BtÌÍBtÂBtžRBt®Bt£×BtBt\Bt
+BtzáBtp€BtffBt\)BtQìBtG®Bt=qBt33Bt(öBt
+žBt{Bt
+=Bt  Br
+BrzáBrp€BrffBr\)BrQìBrG®Br=qBr33Br(öBr
+žBr{Br
+=Br  BqõÃBqë
+BqáHBq×
+BqÌÍBqÂBqžRBq®Bq£×BqBq\Bq
+BqzáBqp€BqffBq\)BqQìBqG®Bq=qBq33Bq(öBq
+žBq{Bq
+=Bq  BpõÃBpë
+BpáHBp×
+BpÌÍBpÂBpžRBp®Bp£×BpBp\Bp
+BpzáBpp€BpffBp\)BpQìBpG®Bp=qBp33Bp(öBp
+žBp{Bp
+=Bp  Bn
+BnzáBnp€BnffBn\)BnQìBnG®Bn=qBn33Bn(öBn
+žBn{Bn
+=Bn  BmõÃBmë
+BmáHBm×
+BmÌÍBmÂBmžRBm®Bm£×BmBm\Bm
+BmzáBmp€BmffBm\)BmQìBmG®Bm=qBm33Bm(öBm
+žBm{Bm
+=Bm  BlõÃBlë
+BláHBl×
+BlÌÍBlÂBlžRBl®Bl£×BlBl\Bl
+BlzáBlp€BlffBl\)BlQìBlG®Bl=qBl33Bl(öBl
+žBl{Bl
+=Bl  Bj
+BjzáBjp€BjffBj\)BjQìBjG®Bj=qBj33Bj(öBj
+žBj{Bj
+=Bj  BiõÃBië
+BiáHBi×
+BiÌÍBiÂBižRBi®Bi£×BiBi\Bi
+BizáBip€BiffBi\)BiQìBiG®Bi=qBi33Bi(öBi
+žBi{Bi
+=Bi  BhõÃBhë
+BháHBh×
+BhÌÍBhÂBhžRBh®Bh£×BhBh\Bh
+BhzáBhp€BhffBh\)BhQìBhG®Bh=qBh33Bh(öBh
+žBh{Bh
+=Bh  Bf
+BfzáBfp€BfffBf\)BfQìBfG®Bf=qBf33Bf(öBf
+žBf{Bf
+=Bf  BeõÃBeë
+BeáHBe×
+BeÌÍBeÂBežRBe®Be£×BeBe\Be
+BezáBep€BeffBe\)BeQìBeG®Be=qBe33Be(öBe
+žBe{Be
+=Be  BdõÃBdë
+BdáHBd×
+BdÌÍBdÂBdžRBd®Bd£×BdBd\Bd
+BdzáBdp€BdffBd\)BdQìBdG®Bd=qBd33Bd(öBd
+žBd{Bd
+=Bd  Bb
+BbzáBbp€BbffBb\)BbQìBbG®Bb=qBb33Bb(öBb
+žBb{Bb
+=Bb  BaõÃBaë
+BaáHBa×
+BaÌÍBaÂBažRBa®Ba£×BaBa\Ba
+BazáBap€BaffBa\)BaQìBaG®Ba=qBa33Ba(öBa
+žBa{Ba
+=Ba  B`õÃB`ë
+B`áHB`×
+B`ÌÍB`ÂB`žRB`®B`£×B`B`\B`
+B`záB`p€B`ffB`\)B`QìB`G®B`=qB`33B`(öB`
+žB`{B`
+=B`  B^
+B^záB^p€B^ffB^\)B^QìB^G®B^=qB^33B^(öB^
+žB^{B^
+=B^  B]õÃB]ë
+B]áHB]×
+B]ÌÍB]ÂB]žRB]®B]£×B]B]\B]
+B]záB]p€B]ffB]\)B]QìB]G®B]=qB]33B](öB]
+žB]{B]
+=B]  B\õÃB\ë
+B\áHB\×
+B\ÌÍB\ÂB\žRB\®B\£×B\B\\B\
+B\záB\p€B\ffB\\)B\QìB\G®B\=qB\33B\(öB\
+žB\{B\
+=B\  BZ
+BZzáBZp€BZffBZ\)BZQìBZG®BZ=qBZ33BZ(öBZ
+žBZ{BZ
+=BZ  BYõÃBYë
+BYáHBY×
+BYÌÍBYÂBYžRBY®BY£×BYBY\BY
+BYzáBYp€BYffBY\)BYQìBYG®BY=qBY33BY(öBY
+žBY{BY
+=BY  BXõÃBXë
+BXáHBX×
+BXÌÍBXÂBXžRBX®BX£×BXBX\BX
+BXzáBXp€BXffBX\)BXQìBXG®BX=qBX33BX(öBX
+žBX{BX
+=BX  BV
+BVzáBVp€BVffBV\)BVQìBVG®BV=qBV33BV(öBV
+žBV{BV
+=BV  BUõÃBUë
+BUáHBU×
+BUÌÍBUÂBUžRBU®BU£×BUBU\BU
+BUzáBUp€BUffBU\)BUQìBUG®BU=qBU33BU(öBU
+žBU{BU
+=BU  BTõÃBTë
+BTáHBT×
+BTÌÍBTÂBTžRBT®BT£×BTBT\BT
+BTzáBTp€BTffBT\)BTQìBTG®BT=qBT33BT(öBT
+žBT{BT
+=BT  BR
+BRzáBRp€BRffBR\)BRQìBRG®BR=qBR33BR(öBR
+žBR{BR
+=BR  BQõÃBQë
+BQáHBQ×
+BQÌÍBQÂBQžRBQ®BQ£×BQBQ\BQ
+BQzáBQp€BQffBQ\)BQQìBQG®BQ=qBQ33BQ(öBQ
+žBQ{BQ
+=BQ  BPõÃBPë
+BPáHBP×
+BPÌÍBPÂBPžRBP®BP£×BPBP\BP
+BPzáBPp€BPffBP\)BPQìBPG®BP=qBP33BP(öBP
+žBP{BP
+=BP  BN
+BNzáBNp€BNffBN\)BNQìBNG®BN=qBN33BN(öBN
+žBN{BN
+=BN  BMõÃBMë
+BMáHBM×
+BMÌÍBMÂBMžRBM®BM£×BMBM\BM
+BMzáBMp€BMffBM\)BMQìBMG®BM=qBM33BM(öBM
+žBM{BM
+=BM  BLõÃBLë
+BLáHBL×
+BLÌÍBLÂBLžRBL®BL£×BLBL\BL
+BLzáBLp€BLffBL\)BLQìBLG®BL=qBL33BL(öBL
+žBL{BL
+=BL  BJ
+BJzáBJp€BJffBJ\)BJQìBJG®BJ=qBJ33BJ(öBJ
+žBJ{BJ
+=BJ  BIõÃBIë
+BIáHBI×
+BIÌÍBIÂBIžRBI®BI£×BIBI\BI
+BIzáBIp€BIffBI\)BIQìBIG®BI=qBI33BI(öBI
+žBI{BI
+=BI  BHõÃBHë
+BHáHBH×
+BHÌÍBHÂBHžRBH®BH£×BHBH\BH
+BHzáBHp€BHffBH\)BHQìBHG®BH=qBH33BH(öBH
+žBH{BH
+=BH  BF
+BFzáBFp€BFffBF\)BFQìBFG®BF=qBF33BF(öBF
+žBF{BF
+=BF  BEõÃBEë
+BEáHBE×
+BEÌÍBEÂBEžRBE®BE£×BEBE\BE
+BEzáBEp€BEffBE\)BEQìBEG®BE=qBE33BE(öBE
+žBE{BE
+=BE  BDõÃBDë
+BDáHBD×
+BDÌÍBDÂBDžRBD®BD£×BDBD\BD
+BDzáBDp€BDffBD\)BDQìBDG®BD=qBD33BD(öBD
+žBD{BD
+=BD  BB
+BBzáBBp€BBffBB\)BBQìBBG®BB=qBB33BB(öBB
+žBB{BB
+=BB  BAõÃBAë
+BAáHBA×
+BAÌÍBAÂBAžRBA®BA£×BABA\BA
+BAzáBAp€BAffBA\)BAQìBAG®BA=qBA33BA(öBA
+žBA{BA
+=BA  B@õÃB@ë
+B@áHB@×
+B@ÌÍB@ÂB@žRB@®B@£×B@B@\B@
+B@záB@p€B@ffB@\)B@QìB@G®B@=qB@33B@(öB@
+žB@{B@
+=B@  B>
+B>záB>p€B>ffB>\)B>QìB>G®B>=qB>33B>(öB>
+žB>{B>
+=B>  B=õÃB=ë
+B=áHB=×
+B=ÌÍB=ÂB=žRB=®B=£×B=B=\B=
+B=záB=p€B=ffB=\)B=QìB=G®B==qB=33B=(öB=
+žB={B=
+=B=  B<õÃB<ë
+B<áHB<×
+B<ÌÍB<ÂB<žRB<®B<£×B<B<\B<
+B<záB<p€B<ffB<\)B<QìB<G®B<=qB<33B<(öB<
+žB<{B<
+=B<  B:
+B:záB:p€B:ffB:\)B:QìB:G®B:=qB:33B:(öB:
+žB:{B:
+=B:  B9õÃB9ë
+B9áHB9×
+B9ÌÍB9ÂB9žRB9®B9£×B9B9\B9
+B9záB9p€B9ffB9\)B9QìB9G®B9=qB933B9(öB9
+žB9{B9
+=B9  B8õÃB8ë
+B8áHB8×
+B8ÌÍB8ÂB8žRB8®B8£×B8B8\B8
+B8záB8p€B8ffB8\)B8QìB8G®B8=qB833B8(öB8
+žB8{B8
+=B8  B6
+B6záB6p€B6ffB6\)B6QìB6G®B6=qB633B6(öB6
+žB6{B6
+=B6  B5õÃB5ë
+B5áHB5×
+B5ÌÍB5ÂB5žRB5®B5£×B5B5\B5
+B5záB5p€B5ffB5\)B5QìB5G®B5=qB533B5(öB5
+žB5{B5
+=B5  B4õÃB4ë
+B4áHB4×
+B4ÌÍB4ÂB4žRB4®B4£×B4B4\B4
+B4záB4p€B4ffB4\)B4QìB4G®B4=qB433B4(öB4
+žB4{B4
+=B4  B2
+B2záB2p€B2ffB2\)B2QìB2G®B2=qB233B2(öB2
+žB2{B2
+=B2  B1õÃB1ë
+B1áHB1×
+B1ÌÍB1ÂB1žRB1®B1£×B1B1\B1
+B1záB1p€B1ffB1\)B1QìB1G®B1=qB133B1(öB1
+žB1{B1
+=B1  B0õÃB0ë
+B0áHB0×
+B0ÌÍB0ÂB0žRB0®B0£×B0B0\B0
+B0záB0p€B0ffB0\)B0QìB0G®B0=qB033B0(öB0
+žB0{B0
+=B0  B.
+B.záB.p€B.ffB.\)B.QìB.G®B.=qB.33B.(öB.
+žB.{B.
+=B.  B-õÃB-ë
+B-áHB-×
+B-ÌÍB-ÂB-žRB-®B-£×B-B-\B-
+B-záB-p€B-ffB-\)B-QìB-G®B-=qB-33B-(öB-
+žB-{B-
+=B-  B,õÃB,ë
+B,áHB,×
+B,ÌÍB,ÂB,žRB,®B,£×B,B,\B,
+B,záB,p€B,ffB,\)B,QìB,G®B,=qB,33B,(öB,
+žB,{B,
+=B,  B*
+B*záB*p€B*ffB*\)B*QìB*G®B*=qB*33B*(öB*
+žB*{B*
+=B*  B)õÃB)ë
+B)áHB)×
+B)ÌÍB)ÂB)žRB)®B)£×B)B)\B)
+B)záB)p€B)ffB)\)B)QìB)G®B)=qB)33B)(öB)
+žB){B)
+=B)  B(õÃB(ë
+B(áHB(×
+B(ÌÍB(ÂB(žRB(®B(£×B(B(\B(
+B(záB(p€B(ffB(\)B(QìB(G®B(=qB(33B((öB(
+žB({B(
+=B(  B&
+B&záB&p€B&ffB&\)B&QìB&G®B&=qB&33B&(öB&
+žB&{B&
+=B&  B%õÃB%ë
+B%áHB%×
+B%ÌÍB%ÂB%žRB%®B%£×B%B%\B%
+B%záB%p€B%ffB%\)B%QìB%G®B%=qB%33B%(öB%
+žB%{B%
+=B%  B$õÃB$ë
+B$áHB$×
+B$ÌÍB$ÂB$žRB$®B$£×B$B$\B$
+B$záB$p€B$ffB$\)B$QìB$G®B$=qB$33B$(öB$
+žB${B$
+=B$  B"
+B"záB"p€B"ffB"\)B"QìB"G®B"=qB"33B"(öB"
+žB"{B"
+=B"  B!õÃB!ë
+B!áHB!×
+B!ÌÍB!ÂB!žRB!®B!£×B!B!\B!
+B!záB!p€B!ffB!\)B!QìB!G®B!=qB!33B!(öB!
+žB!{B!
+=B!  B õÃB ë
+B áHB ×
+B ÌÍB ÂB žRB ®B £×B B \B 
+B záB p€B ffB \)B QìB G®B =qB 33B (öB 
+žB {B 
+=B   B
+
+B
+záB
+p€B
+ffB
+\)B
+QìB
+G®B
+=qB
+33B
+(öB
+
+žB
+{B
+
+=B
+  B
+õÃB
+ë
+B
+áHB
+×
+B
+ÌÍB
+ÂB
+žRB
+®B
+£×B
+B
+\B
+
+B
+záB
+p€B
+ffB
+\)B
+QìB
+G®B
+=qB
+33B
+(öB
+
+žB
+{B
+
+=B
+  B
+õÃB
+ë
+B
+áHB
+×
+B
+ÌÍB
+ÂB
+žRB
+®B
+£×B
+B
+\B
+
+B
+záB
+p€B
+ffB
+\)B
+QìB
+G®B
+=qB
+33B
+(öB
+
+žB
+{B
+
+=B
+  B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  B
+õÃB
+ë
+B
+áHB
+×
+B
+ÌÍB
+ÂB
+žRB
+®B
+£×B
+B
+\B
+
+B
+záB
+p€B
+ffB
+\)B
+QìB
+G®B
+=qB
+33B
+(öB
+
+žB
+{B
+=B
+  B
+õÃB
+ë
+B
+áHB
+×
+B
+ÌÍB
+ÂB
+žRB
+®B
+£×B
+B
+\B
+
+B
+záB
+p€B
+ffB
+\)B
+QìB
+G®B
+=qB
+33B
+(öB
+
+žB
+{B
+
+=B
+  B
+
+B
+záB
+p€B
+ffB
+\)B
+QìB
+G®B
+=qB
+33B
+(öB
+
+žB
+{B
+
+=B
+  B	õÃB	ë
+B	áHB	×
+B	ÌÍB	ÂB	žRB	®B	£×B	B	\B	
+B	záB	p€B	ffB	\)B	QìB	G®B	=qB	33B	(öB	
+žB	{B	
+=B	  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  B õÃB ë
+B áHB ×
+B ÌÍB ÂB žRB ®B £×B B \B 
+B záB p€B ffB \)B QìB G®B =qB 33B (öB 
+žB {B 
+=B   Aý
+=AüõÃAüáHAüÌÍAüžRAü£×Aü\AüzáAüffAüQìAü=qAü(öAü{Aü  Aûë
+Aû×
+AûÂAû®AûAû
+Aûp€Aû\)AûG®Aû33Aû
+žAû
+=AúõÃAúáHAúÌÍAúžRAú£×Aú\AúzáAúffAúQìAú=qAú(öAú{Aú  Aùë
+Aù×
+AùÂAù®AùAù
+Aùp€Aù\)AùG®Aù33Aù
+žAù
+=AøõÃAøáHAøÌÍAøžRAø£×Aø\AøzáAøffAøQìAø=qAø(öAø{Aø  Aõ
+=AôõÃAôáHAôÌÍAôžRAô£×Aô\AôzáAôffAôQìAô=qAô(öAô{Aô  Aóë
+Aó×
+AóÂAó®AóAó
+Aóp€Aó\)AóG®Aó33Aó
+žAó
+=AòõÃAòáHAòÌÍAòžRAò£×Aò\AòzáAòffAòQìAò=qAò(öAò{Aò  Añë
+Añ×
+AñÂAñ®AñAñ
+Añp€Añ\)AñG®Añ33Añ
+žAñ
+=AðõÃAðáHAðÌÍAðžRAð£×Að\AðzáAðffAðQìAð=qAð(öAð{Að  Aí
+=AìõÃAìáHAìÌÍAìžRAì£×Aì\AìzáAìffAìQìAì=qAì(öAì{Aì  Aëë
+Aë×
+AëÂAë®AëAë
+Aëp€Aë\)AëG®Aë33Aë
+žAë
+=AêõÃAêáHAêÌÍAêžRAê£×Aê\AêzáAêffAêQìAê=qAê(öAê{Aê  Aéë
+Aé×
+AéÂAé®AéAé
+Aép€Aé\)AéG®Aé33Aé
+žAé
+=AèõÃAèáHAèÌÍAèžRAè£×Aè\AèzáAèffAèQìAè=qAè(öAè{Aè  Aå
+=AäõÃAäáHAäÌÍAäžRAä£×Aä\AäzáAäffAäQìAä=qAä(öAä{Aä  Aãë
+Aã×
+AãÂAã®AãAã
+Aãp€Aã\)AãG®Aã33Aã
+žAã
+=AâõÃAâáHAâÌÍAâžRAâ£×Aâ\AâzáAâffAâQìAâ=qAâ(öAâ{Aâ  Aáë
+Aá×
+AáÂAá®AáAá
+Aáp€Aá\)AáG®Aá33Aá
+žAá
+=AàõÃAàáHAàÌÍAàžRAà£×Aà\AàzáAàffAàQìAà=qAà(öAà{Aà  AÝ
+=AÜõÃAÜáHAÜÌÍAÜžRAÜ£×AÜ\AÜzáAÜffAÜQìAÜ=qAÜ(öAÜ{AÜ  AÛë
+AÛ×
+AÛÂAÛ®AÛAÛ
+AÛp€AÛ\)AÛG®AÛ33AÛ
+žAÛ
+=AÚõÃAÚáHAÚÌÍAÚžRAÚ£×AÚ\AÚzáAÚffAÚQìAÚ=qAÚ(öAÚ{AÚ  AÙë
+AÙ×
+AÙÂAÙ®AÙAÙ
+AÙp€AÙ\)AÙG®AÙ33AÙ
+žAÙ
+=AØõÃAØáHAØÌÍAØžRAØ£×AØ\AØzáAØffAØQìAØ=qAØ(öAØ{AØ  AÕ
+=AÔõÃAÔáHAÔÌÍAÔžRAÔ£×AÔ\AÔzáAÔffAÔQìAÔ=qAÔ(öAÔ{AÔ  AÓë
+AÓ×
+AÓÂAÓ®AÓAÓ
+AÓp€AÓ\)AÓG®AÓ33AÓ
+žAÓ
+=AÒõÃAÒáHAÒÌÍAÒžRAÒ£×AÒ\AÒzáAÒffAÒQìAÒ=qAÒ(öAÒ{AÒ  AÑë
+AÑ×
+AÑÂAÑ®AÑAÑ
+AÑp€AÑ\)AÑG®AÑ33AÑ
+žAÑ
+=AÐõÃAÐáHAÐÌÍAÐžRAÐ£×AÐ\AÐzáAÐffAÐQìAÐ=qAÐ(öAÐ{AÐ  AÍ
+=AÌõÃAÌáHAÌÌÍAÌžRAÌ£×AÌ\AÌzáAÌffAÌQìAÌ=qAÌ(öAÌ{AÌ  AËë
+AË×
+AËÂAË®AËAË
+AËp€AË\)AËG®AË33AË
+žAË
+=AÊõÃAÊáHAÊÌÍAÊžRAÊ£×AÊ\AÊzáAÊffAÊQìAÊ=qAÊ(öAÊ{AÊ  AÉë
+AÉ×
+AÉÂAÉ®AÉAÉ
+AÉp€AÉ\)AÉG®AÉ33AÉ
+žAÉ
+=AÈõÃAÈáHAÈÌÍAÈžRAÈ£×AÈ\AÈzáAÈffAÈQìAÈ=qAÈ(öAÈ{AÈ  AÅ
+=AÄõÃAÄáHAÄÌÍAÄžRAÄ£×AÄ\AÄzáAÄffAÄQìAÄ=qAÄ(öAÄ{AÄ  AÃë
+AÃ×
+AÃÂAÃ®AÃAÃ
+AÃp€AÃ\)AÃG®AÃ33AÃ
+žAÃ
+=AÂõÃAÂáHAÂÌÍAÂžRAÂ£×AÂ\AÂzáAÂffAÂQìAÂ=qAÂ(öAÂ{AÂ  AÁë
+AÁ×
+AÁÂAÁ®AÁAÁ
+AÁp€AÁ\)AÁG®AÁ33AÁ
+žAÁ
+=AÀõÃAÀáHAÀÌÍAÀžRAÀ£×AÀ\AÀzáAÀffAÀQìAÀ=qAÀ(öAÀ{AÀ  Aœ
+=AŒõÃAŒáHAŒÌÍAŒžRAŒ£×AŒ\AŒzáAŒffAŒQìAŒ=qAŒ(öAŒ{AŒ  A»ë
+A»×
+A»ÂA»®A»A»
+A»p€A»\)A»G®A»33A»
+žA»
+=AºõÃAºáHAºÌÍAºžRAº£×Aº\AºzáAºffAºQìAº=qAº(öAº{Aº  A¹ë
+A¹×
+A¹ÂA¹®A¹A¹
+A¹p€A¹\)A¹G®A¹33A¹
+žA¹
+=AžõÃAžáHAžÌÍAžžRAž£×Až\AžzáAžffAžQìAž=qAž(öAž{Až  Aµ
+=AŽõÃAŽáHAŽÌÍAŽžRAŽ£×AŽ\AŽzáAŽffAŽQìAŽ=qAŽ(öAŽ{AŽ  A³ë
+A³×
+A³ÂA³®A³A³
+A³p€A³\)A³G®A³33A³
+žA³
+=A²õÃA²áHA²ÌÍA²žRA²£×A²\A²záA²ffA²QìA²=qA²(öA²{A²  A±ë
+A±×
+A±ÂA±®A±A±
+A±p€A±\)A±G®A±33A±
+žA±
+=A°õÃA°áHA°ÌÍA°žRA°£×A°\A°záA°ffA°QìA°=qA°(öA°{A°  A­
+=A¬õÃA¬áHA¬ÌÍA¬žRA¬£×A¬\A¬záA¬ffA¬QìA¬=qA¬(öA¬{A¬  A«ë
+A«×
+A«ÂA«®A«A«
+A«p€A«\)A«G®A«33A«
+žA«
+=AªõÃAªáHAªÌÍAªžRAª£×Aª\AªzáAªffAªQìAª=qAª(öAª{Aª  A©ë
+A©×
+A©ÂA©®A©A©
+A©p€A©\)A©G®A©33A©
+žA©
+=AšõÃAšáHAšÌÍAšžRAš£×Aš\AšzáAšffAšQìAš=qAš(öAš{Aš  A¥
+=A€õÃA€áHA€ÌÍA€žRA€£×A€\A€záA€ffA€QìA€=qA€(öA€{A€  A£ë
+A£×
+A£ÂA£®A£A£
+A£p€A£\)A£G®A£33A£
+žA£
+=A¢õÃA¢áHA¢ÌÍA¢žRA¢£×A¢\A¢záA¢ffA¢QìA¢=qA¢(öA¢{A¢  A¡ë
+A¡×
+A¡ÂA¡®A¡A¡
+A¡p€A¡\)A¡G®A¡33A¡
+žA¡
+=A õÃA áHA ÌÍA žRA £×A \A záA ffA QìA =qA (öA {A   A
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Aë
+A×
+AÂA®AA
+Ap€A\)AG®A33A
+žA
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Aë
+A×
+AÂA®AA
+Ap€A\)AG®A33A
+žA
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  A
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Aë
+A×
+AÂA®AA
+Ap€A\)AG®A33A
+žA
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Aë
+A×
+AÂA®AA
+Ap€A\)AG®A33A
+žA
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  A
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Aë
+A×
+AÂA®AA
+Ap€A\)AG®A33A
+žA
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Aë
+A×
+AÂA®AA
+Ap€A\)AG®A33A
+žA
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  A
+
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Aë
+A×
+AÂA®AA
+Ap€A\)AG®A33A
+žA
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Aë
+A×
+AÂA®AA
+Ap€A\)AG®A33A
+žA
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Az{Ayë
+AyÂAyAyp€AyG®Ay
+žAxõÃAxÌÍAx£×AxzáAxQìAx(öAx  Aw×
+Aw®Aw
+Aw\)Aw33Aw
+=AváHAvžRAv\AvffAv=qAv{Auë
+AuÂAuAup€AuG®Au
+žAtõÃAtÌÍAt£×AtzáAtQìAt(öAt  As×
+As®As
+As\)As33As
+=AráHAržRAr\ArffAr=qAr{Aqë
+AqÂAqAqp€AqG®Aq
+žApõÃApÌÍAp£×ApzáApQìAp(öAp  Aj{Aië
+AiÂAiAip€AiG®Ai
+žAhõÃAhÌÍAh£×AhzáAhQìAh(öAh  Ag×
+Ag®Ag
+Ag\)Ag33Ag
+=AfáHAfžRAf\AfffAf=qAf{Aeë
+AeÂAeAep€AeG®Ae
+žAdõÃAdÌÍAd£×AdzáAdQìAd(öAd  Ac×
+Ac®Ac
+Ac\)Ac33Ac
+=AbáHAbžRAb\AbffAb=qAb{Aaë
+AaÂAaAap€AaG®Aa
+žA`õÃA`ÌÍA`£×A`záA`QìA`(öA`  AZ{AYë
+AYÂAYAYp€AYG®AY
+žAXõÃAXÌÍAX£×AXzáAXQìAX(öAX  AW×
+AW®AW
+AW\)AW33AW
+=AVáHAVžRAV\AVffAV=qAV{AUë
+AUÂAUAUp€AUG®AU
+žATõÃATÌÍAT£×ATzáATQìAT(öAT  AS×
+AS®AS
+AS\)AS33AS
+=ARáHARžRAR\ARffAR=qAR{AQë
+AQÂAQAQp€AQG®AQ
+žAPõÃAPÌÍAP£×APzáAPQìAP(öAP  AJ{AIë
+AIÂAIAIp€AIG®AI
+žAHõÃAHÌÍAH£×AHzáAHQìAH(öAH  AG×
+AG®AG
+AG\)AG33AG
+=AFáHAFžRAF\AFffAF=qAF{AEë
+AEÂAEAEp€AEG®AE
+žADõÃADÌÍAD£×ADzáADQìAD(öAD  AC×
+AC®AC
+AC\)AC33AC
+=ABáHABžRAB\ABffAB=qAB{AAë
+AAÂAAAAp€AAG®AA
+žA@õÃA@ÌÍA@£×A@záA@QìA@(öA@  A:{A9ë
+A9ÂA9A9p€A9G®A9
+žA8õÃA8ÌÍA8£×A8záA8QìA8(öA8  A7×
+A7®A7
+A7\)A733A7
+=A6áHA6žRA6\A6ffA6=qA6{A5ë
+A5ÂA5A5p€A5G®A5
+žA4õÃA4ÌÍA4£×A4záA4QìA4(öA4  A3×
+A3®A3
+A3\)A333A3
+=A2áHA2žRA2\A2ffA2=qA2{A1ë
+A1ÂA1A1p€A1G®A1
+žA0õÃA0ÌÍA0£×A0záA0QìA0(öA0  A*{A)ë
+A)ÂA)A)p€A)G®A)
+žA(õÃA(ÌÍA(£×A(záA(QìA((öA(  A'×
+A'®A'
+A'\)A'33A'
+=A&áHA&žRA&\A&ffA&=qA&{A%ë
+A%ÂA%A%p€A%G®A%
+žA$õÃA$ÌÍA$£×A$záA$QìA$(öA$  A#×
+A#®A#
+A#\)A#33A#
+=A"áHA"žRA"\A"ffA"=qA"{A!ë
+A!ÂA!A!p€A!G®A!
+žA õÃA ÌÍA £×A záA QìA (öA   A{Aë
+AÂAAp€AG®A
+žAõÃAÌÍA£×AzáAQìA(öA  A×
+A®A
+A\)A33A
+=AáHAžRA\AffA=qA{Aë
+AÂAAp€AG®A
+žAõÃAÌÍA£×AzáAQìA(öA  A×
+A®A
+A\)A33A
+=AáHAžRA\AffA=qA{Aë
+AÂAAp€AG®A
+žAõÃAÌÍA£×AzáAQìA(öA  A
+{A	ë
+A	ÂA	A	p€A	G®A	
+žAõÃAÌÍA£×AzáAQìA(öA  A×
+A®A
+A\)A33A
+=AáHAžRA\AffA=qA{Aë
+AÂAAp€AG®A
+žAõÃAÌÍA£×AzáAQìA(öA  A×
+A®A
+A\)A33A
+=AáHAžRA\AffA=qA{Aë
+AÂAAp€AG®A
+žA õÃA ÌÍA £×A záA QìA (öA   @ô(ö@ó×
+@ó
+@ó33@òáH@ò\@ò=q@ñë
+@ñ@ñG®@ðõÂ@ð£×@ðQì@ð  @ï®@ï\)@ï
+=@îžR@îff@î{@íÂ@íp€@í
+ž@ìÌÍ@ìzá@ì(ö@ë×
+@ë
+@ë33@êáH@ê\@ê=q@éë
+@é@éG®@èõÃ@è£×@èQì@è  @ç®@ç\)@ç
+=@æžR@æff@æ{@åÂ@åp€@å
+ž@äÌÍ@äzá@ä(ö@ã×
+@ã
+@ã33@âáH@â\@â=q@áë
+@á@áG®@àõÃ@à£×@àQì@à  @Ô(ö@Ó×
+@Ó
+@Ó33@ÒáH@Ò\@Ò=q@Ñë
+@Ñ@ÑG®@ÐõÂ@Ð£×@ÐQì@Ð  @Ï®@Ï\)@Ï
+=@ÎžR@Îff@Î{@ÍÂ@Íp€@Í
+ž@ÌÌÍ@Ìzá@Ì(ö@Ë×
+@Ë
+@Ë33@ÊáH@Ê\@Ê=q@Éë
+@É@ÉG®@ÈõÃ@È£×@ÈQì@È  @Ç®@Ç\)@Ç
+=@ÆžR@Æff@Æ{@ÅÂ@Åp€@Å
+ž@ÄÌÍ@Äzá@Ä(ö@Ã×
+@Ã
+@Ã33@ÂáH@Â\@Â=q@Áë
+@Á@ÁG®@ÀõÃ@À£×@ÀQì@À  @Ž(ö@³×
+@³
+@³33@²áH@²\@²=q@±ë
+@±@±G®@°õÂ@°£×@°Qì@°  @¯®@¯\)@¯
+=@®žR@®ff@®{@­Â@­p€@­
+ž@¬ÌÍ@¬zá@¬(ö@«×
+@«
+@«33@ªáH@ª\@ª=q@©ë
+@©@©G®@šõÃ@š£×@šQì@š  @§®@§\)@§
+=@ŠžR@Šff@Š{@¥Â@¥p€@¥
+ž@€ÌÍ@€zá@€(ö@£×
+@£
+@£33@¢áH@¢\@¢=q@¡ë
+@¡@¡G®@ õÃ@ £×@ Qì@   @(ö@×
+@
+@33@áH@\@=q@ë
+@@G®@õÂ@£×@Qì@  @®@\)@
+=@žR@ff@{@Â@p€@
+ž@ÌÍ@zá@(ö@×
+@
+@33@áH@\@=q@ë
+@@G®@õÃ@£×@Qì@  @®@\)@
+=@žR@ff@{@
+Â@
+p€@
+
+ž@ÌÍ@zá@(ö@×
+@
+@33@áH@\@=q@ë
+@@G®@õÃ@£×@Qì@  @hQì@g®@g
+>@fff@eÂ@e
+ž@dzá@c×
+@c33@b\@aë
+@aG®@`£×@`  @_\)@^žR@^{@]p€@\ÌÍ@\(ö@[
+@ZáH@Z=q@Y@XõÂ@XQì@W®@W
+>@Vff@UÂ@U
+ž@Tzá@S×
+@S33@R\@Që
+@QG®@P£×@P  @O\)@NžR@N{@Mp€@LÌÍ@L(ö@K
+@JáH@J=q@I@HõÃ@HQì@G®@G
+=@Fff@EÂ@E
+ž@Dzá@C×
+@C33@B\@Aë
+@AG®@@£×@@  @(Qì@'®@'
+>@&ff@%Â@%
+ž@$zá@#×
+@#33@"\@!ë
+@!G®@ £×@   @\)@
+žR@
+{@
+p€@
+ÌÍ@
+(ö@
+@áH@=q@@õÂ@Qì@®@
+>@ff@Â@
+ž@zá@×
+@33@\@ë
+@G®@£×@  @\)@žR@{@
+p€@
+ÌÍ@
+(ö@
+
+@
+áH@
+=q@	@õÃ@Qì@®@
+=@ff@Â@
+ž@zá@×
+@33@\@ë
+@G®@ £×@   ?Ð£×?Ï\)?Î{?ÌÌÍ?Ë
+
+?Ê=p?ÈõÂ?Ç®?Æff?Å
+ž?Ã×
+?Â\?ÁG®?À  ?ŸžR?œp€?Œ(ö?ºáH?¹?žQì?·
+>?µÂ?Žzá?³33?±ë
+?°£×?¯\)?®{?¬ÌÍ?«
+?ª=q?šõÂ?§®?Šff?¥
+ž?£×
+?¢\?¡G®?   ?žR?p€?(ö?áH??Qì?
+>?Â?zá?33?ë
+?£×?\)?{?ÌÍ?
+?=q?õÃ?®?ff?
+
+ž?×
+?\?G®?  ?!G®?
+žR?
+(ö??
+=?zá?ë
+?\)?
+ÌÍ?
+=q?®?
+ž?\?   >úáH>õÂ>ð£×>ë
+>æff>áG®>Ü(ö>×
+=>Ñë
+>ÌÌÍ>Ç®>Â\>œp€>žQì>³33>®{>šõÃ>£×
+>žR>>zá>\)>=q>
+
+ž>  >uÂ>k
+>aG®>W
+=>LÌÍ>B\>8Qì>.{>#×
+>>\)>
+ž=õÂ=áG®=ÌÌÍ=žQì=£×
+=\)=uÂ=LÌÍ=#×
+<õÂ<£×
+<#×
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                  -32 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   91 / length of data axis 1                          NAXIS2  =                   91 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~bB~Æ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BxºrB{-B~[B~vK¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BsKBuæBx²ÜB{³B~LB~gÏ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  Bmj#Bp=ÞBs
+ŽBu×Bx€aB{q7B~>B~YT¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BgÁûBj¶BmbBp/cBrü9BuÉBxæB{bœB~/B~JÙ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BbÓBdíBgºdBj;BmTBp çBríŸBuºBxkB{TAB~!B~<^¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B\q«B_EfBb<BdßBg«éBjx¿BmEBpmBrßCBu¬BxxðB{EÆB~B~-ã¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BVÉBY?B\jB_6ìBbÂBdÐBgoBjjFBm7
+BpòBrÐÉBuBxjuB{7LB~"B~g¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BQ!\BSõBVÁíBYÄB\[B_(pBaõGBdÂ
+BgôBj[ÊBm(¡BoõwBrÂMBu$Bx[úB{(ÐB}õ§B~ì¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BKy4BNLïBQÅBSæBV³rBYHB\MB_öBaæÌBd³¢BgyBjMOBm%BoæüBr³ÒBušBxMB{UB}ç+B~q¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BEÑ
+BH€ÇBKqBN>tBQ
+JBSØ BV€÷BYqÎB\>€B_
+zBaØQBd¥'BgqýBj>ÔBm
+ªBoØBr¥WBur-Bx?B{
+ÚB}Ø°B}óö¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B@(äBBüBEÉuBHLBKc"BN/øBPüÏBSÉŠBV|BYcRB\0)B^üÿBaÉÕBd¬BgcBj0XBlý/BoÊBrÛBuc²Bx0Bzý_B}Ê5B}åz¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B:œB=TxB@!NBBî%BEºûBHÑBKTšBN!BPîUBS»+BVBYTØB\!®B^î
+Ba»[Bd1BgUBj!ÞBlîŽBo»BraBuU8Bx"BzîäB}»»B}Öÿ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B4ØB7¬PB:y&B=EýB@ÓBBß©BE¬BHyWBKF-BNBPßÚBS¬°BVyBYF]B\3B^à	Ba¬àBdy¶BgFBjcBlà9Bo­BryæBuFŒBxBzàiB}­?B}È¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B/0mB2(B4ÐþB7ÕB:j«B=7B@XBBÑ/BEBHjÛBK7²BNBPÑ^BS5BVk
+BY7áB\žB^ÑBadBdk;Bg8BjèBlÑŸBoBrkkBu8ABxBzÑîB}ÄB}º¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B)EB,\ B/(ÖB1õ­B4ÂB7YB:\0B=)B?õÝBBÂ³BEBH\`BK)6BMö
+BPÂãBS¹BV\BY)fB[ö<B^ÃBaéBd\ÀBg)BiölBlÃCBoBr\ïBu)ÆBwöBzÃrB}HB}«¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B#à
+B&³ØB)®B,M
+B/[B1ç1B4ŽB7ßB:MµB=B?çbBBŽ8BEBHMåBK»BMçBPŽhBS>BVNBYëB[çÁB^ŽBanBdNDBgBiçñBlŽÇBoBrNtBuJBwè BzŽ÷B}ÍB}¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B
+7õB!
+°B#ØB&¥]B)r3B,?	B/
+àB1Ø·B4¥B7rcB:?:B=
+B?ØæBB¥œBErBH?iBK
+@BMÙBP¥ìBSrÃBV?BY
+pB[ÙFB^Š
+BaróBd?ÉBg
+BiÙvBlŠLBos"Br?øBu
+ÏBwÙ¥BzŠ|B}sRB}¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BÎBcB
+0_B ý6B#Ê
+B&âB)c¹B,0B.ýfB1Ê<B4B7céB:0¿B<ýB?ÊlBBBBEdBH0ïBJýÅBMÊBPrBSdIBV1BXýõB[ÊÌB^¢BadxBd1OBfþ%BiÊûBlÑBodšBr1~BtþUBwË+BzB}dØB}¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BçŠB»aB7BUB
+!äB îºB#»B&hB)U>B,"B.îëB1»ÁB4B7UnB:"DB<ïB?»ñBBÇBEUBH"tBJïJBMŒ!BP÷BSUÍBV"€BXïzB[ŒPB^'BaUýBd"ÓBfï©BiŒBlVBoV-Br#BtïÙBwŒ°BzB}V\B}q ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B
+?~B9BàB¬æByŒBFB
+iB à@B#­B&yìB)FÃB,B.àoB1­FB4z
+B7FòB:ÉB<àB?­uBBzLBEG"BHùBJàÏBM­¥BPz|BSGRBV(BXàÿB[­ÕB^z«BaGBdXBfá.Bi®BlzÛBoG±BrBtá^Bw®4Bz{
+B}GáB}c$¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BVB
+kB
+7çBŸBÑBjBkAB8B
+îB ÑÄB#B&kqB)8GB,
+B.ÑôB1ÊB4k¡B78wB:MB<Ò$B?úBBkÑBE8§BH}BJÒTBM*BPl BS8×BV­BXÒB[YB^l0Ba9BdÝBfÒ³BiBll`Bo96Br
+BtÒãBw¹BzlB}9fB}Tª¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  Bï.BÂéB¿B
+\B
+)lBöBBÃBðB\ÆB)B
+ösB ÃIB#B&\öB))ÌB+ö¢B.ÃyB1OB4]%B7)üB9öÒB<Ã©B?BB]UBE*,BG÷BJÃØBM¯BP]
+BS*[BU÷1BXÄB[ÞB^]µBa*Bc÷aBfÄ8BiBl]äBo*»Bq÷BtÄgBw>Bz^B}*ëB}F.¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  Aø
+Aþ5BçBŽnBDB
+NB
+ñBçÈBŽBtBNKB!B
+ç÷B ŽÎB#€B&NzB)QB+è'B.ŽýB1ÔB4NªB7B9èWB<µ-B?BBNÚBE°BGèBJµ]BM3BPO	BSàBUè¶BXµB[cB^O9Ba
+BcèæBfµŒBiBlOiBo
+?BqéBtµíBwÃBzOB}
+pB}7³¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  Aí=ŒAòå3Aø~àAþBÙ
+B¥òBrÉB
+? B
+
+vBÙLBŠ#BrùB?ÏB
+ŠB
+Ù|B ŠRB#s)B&?ÿB)
+ÕB+Ù¬B.ŠB1sYB4@/B7
+B9ÙÜB<Š²B?sBB@_BE
+5BGÚ
+BJŠáBMsžBP@BS
+eBUÚ;BX§B[sèB^@ŸBa
+BcÚkBf§ABitBl@îBo
+ÅBqÚBt§qBwtHBzA
+B}
+ôB})8¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AáílAçãAí.AòÈ=AøaêAýûBÊ¡BxBdNB
+1$B
+ýûBÊÑB§Bd~B1TBþ*B
+ËB ×B#d­B&1B(þZB+Ë1B.B1dÝB41ŽB6þB9Ë`B<7B?e
+BB1ãBDþ¹BGËBJfBMe=BP2BRþéBUËÀBXB[elB^2CB`ÿBcËïBfÆBieBl2sBnÿIBqÌ BtöBweÌBz2£B|ÿyB}Œ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AÖ
+AÜDAáÞ@AçwíAíAò«GAøDóAýÞ BŒ&BüBUÓB
+"©B
+ïBŒVB,BVB"ÙBï¯B
+Œ
+B \B#V2B&#	B(ïßB+ŒµB.B1VbB4#8B6ðB9ŒåB<»B?VBB#hBDð>BGœBJëBMVÁBP#BRðnBUœDBXB[VñB^#ÇB`ðBcœuBfKBiW!Bl#øBnðÎBqœ€Bt{BwWQBz$'B|ðþB}
+A¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AËLÌAÐôCAÖðAÜ'AáÁJAçZ÷Aìô£AòPAø'üAýÁ©B­«BzBGWB
+.B
+áB­ÚBz±BGB]Bá4B
+®
+B záB#G·B&B(ádB+®:B.{B1GçB4œB6áB9®iB<{@B?HBBíBDáÃBG®BJ{pBMHFBP
+BRáóBU®ÉBX{B[HvB^MB`â#Bc®ùBf{ÐBiHŠBl|BnâSBq¯)Bt{ÿBwHÖBz¬B|âB|ýÆ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A¿ü|AÅ£óAË= AÐ×MAÖpúAÜ
+§Aá€SAç> Aì×¬AòqYAø
+Aý€²B/BlB8ÜB
+²B
+ÒB_Bl5B9
+BâBÒ¹B
+B leB#9<B&B(ÒèB+¿B.lB19kB4AB6ÓB9îB<lÅB?9BBqBDÓHBG 
+BJlôBM9ËBP¡BRÓwBU NBXm%B[9ûB^ÑB`ÓšBc ~BfmTBi:+BlBnÓ×Bq ®BtmBw:ZBz1B|ÔB|ïJ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AŽ¬,AºS£A¿íPAÅýAË ªAÐºWAÖTAÛí°Aá\Aç!	Aìº¶AòTbA÷îAýŒBŽB]B*aB	÷7B
+Ä
+BäB]ºB*B÷gBÄ=B
+B ]êB#*ÀB%÷B(ÄmB+CB.^B1*ðB3÷ÆB6ÄB9sB<^IB?+ BA÷öBDÄÌBG£BJ^yBM+OBOø&BRÄýBUÓBX^©B[+B]øVB`Å,BcBf^ÙBi+¯BkøBnÅ\Bq2Bt_	Bw+ßByøµB|ÅB|àÏ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A©[ÜA¯SAŽ Aº6­A¿ÐZAÅjAË³AÐ`AÖ7
+AÛÐ¹AájfAçAì¿Aò7lA÷ÑAýjÆB9BOBåB	èŒB
+µBiBO?B
+BèìBµÂB
+B OoB#
+EB%éB(µñB+ÈB.OB1
+uB3éKB6¶!B9øB<OÎB?
+€BAé{BD¶QBG'BJOþBM
+ÕBOé«BR¶BUXBXP.B[
+B]éÛB`¶±BcBfP^Bi
+4Bkê
+Bn¶áBq·BtPBw
+dByê:B|·B|ÒT¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A
+A£³A©L¯A®æ\AŽ	Aº¶A¿³bAÅMAÊæ»AÐhAÖAÛ³ÁAáMnAæçAìÈAòuA÷Ž"AýMÎBsœB@B
+jB	ÚAB
+§BsíB@ÄB
+BÚpB§GB
+t
+B @óB#
+ÉB%Ú B(§vB+tMB.A#B1
+ùB3ÚÐB6§ŠB9t|B<ASB?)BAÚÿBD§ÖBGt­BJABMYBOÛ0BRšBUtÜBXA³B[B]Û_B`š6Bcu
+BfAâBi¹BkÛBnšeBqu<BtBBwèByÛ¿B|šB|ÃØ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A»;Ab²Aü_A£
+A©/¹A®ÉfAŽcA¹ü¿A¿kAÅ0AÊÉÅAÐcqAÕý
+AÛËAá0xAæÊ%AìcÒAñý~A÷+Aý0×BeBB2BþïB	ËÅB
+BerB2HBÿBËõBËB
+e¡B 2xB"ÿNB%Ì%B(ûB+eÑB.2šB0ÿ~B3ÌTB6+B9fB<2×B>ÿ®BAÌ
+BD[BGf1BJ3BLÿÞBOÌŽBRBUfaBX37B[ B]ÌäB`ºBcfBf3gBi =BkÍBnêBqfÀBt3Bw mByÍCB|B|µ]¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AjëAbA¬AEŒAßiA£yA©ÂA®¬oAŽFA¹ßÈA¿yuAÅ!AÊ¬ÎAÐF{AÕà(AÛyÕAáAæ­.AìFÛAñàA÷z4AýáBVÇB#BðtB	œJB
+ BV÷B#ÍBð£BœyBPB
+W&B #ýB"ðÓB%œ©B(B+WVB.$,B0ñB3œÙB6¯B9WB<$]B>ñ3BAŸ	BDàBGW¶BJ$BLñcBOŸ9BRBUWæBX$ŒBZñB]ŸiB`?BcXBf$ìBhñÂBkŸBnoBqXEBt%BvñòByŸÈB|B|Šâ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  Ax58AÂA[¿AõlAA(ÆAÂrA£\AšõËA®xAŽ)%A¹ÂÑA¿\~AÄö+AÊØAÐ)
+AÕÃ2AÛ\ÞAàöAæ7Aì)äAñÃA÷]=AüöêBHLB"BáøB	®ÏB
+{¥BH{BQBâ(B®þB{ÕB
+H«B B"âXB%¯.B(|B+HÛB.±B0âB3¯^B6|5B9I
+B<áB>âžBA¯BD|dBGI;BJBLâçBO¯ŸBR|BUIjBXABZãB]¯íB`|ÄBcIBfpBhãGBk°
+Bn|óBqIÊBt BvãvBy°MB|}$B|g¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AaAlãAxßA¥
+A>ÉAØvAr"A
+ÏA¥{A£?(AšØÕA®rAŽ
+.A¹¥ÛA¿?AÄÙ5AÊrâAÐ
+AÕŠ;AÛ?çAàÙAæsAAì
+íAñŠA÷@GAüÙóB9ÐB§BÓ}B	 SB
+m)B: BÖBÓ­B BmYB
+:0B B"ÓÜB% ³B(mB+:_B.6B0Ô
+B3 ãB6m¹B9:B<fB>Ô<BA¡BDméBG:¿BJBLÔlBO¡BBRnBU:ïBXÅBZÔB]¡rB`nHBc;BfõBhÔËBk¡¢BnnxBq;NBt%BvÔüBy¡ÒB|nšB|ì¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AJóûAVBèAav@Al©AwÜñA&A!ÒA»AU+AîØA
+A£"1Aš»ÞA®UA³ï8A¹åA¿"AÄŒ>AÊUëAÏïAÕDAÛ"ñAàŒAæVJAëï÷Añ£A÷#QAüŒýB+UBø+BÅB	ØB
+^®B+
+Bø[BÅ1BB^ÞB
++ŽBøB"ÅaB%7B(_B++åB-ø»B0ÅB3hB6_>B9,B;øëB>ÅÁBABD_nBG,DBIùBLÅñBOÇBR_BU,tBWùJBZÆ B]÷B`_ÍBc,£BeùzBhÆPBk&Bn_ýBq,ÔBsùªBvÆByWB|`-B|{p¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A4S]A?¢JAJÕ¢AVûAa<SAlo¬Aw£Ak/AÛAA85AÑáAkA£;AšèA®8A³ÒBA¹kîA¿AÄGAÊ8ôAÏÒ¡AÕlMAÛúAà§Aæ9SAëÓAñl®A÷ZAü B
+ÙBé°B¶B	]B
+P3B
+	BéàB¶¶BBPcB
+
+9BêB"¶æB%œB(PB+
+iB-ê@B0·B3ìB6PÃB9
+B;êoB>·FBA
+BDPòBG
+ÉBIêBL·uBOLBRQ"BU
+øBWêÏBZ·¥B]{B`QRBc
+(BeêþBh·ÕBk¬BnQBq
+XBsë/BvžByÛB|Q²B|lõ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A
+²¿A)¬A45A?h]AJµAUÏAafAl5¿AwiAN8AçåAA>AŽëANA¢èEAšòA®A³µKA¹N÷AŸè€AÄQAÊýAÏµªAÕOWAÚéAà±Aæ
+^Aë¶
+AñO·AöécAüB^BÛ5Bš
+B	táB
+AžBBÛdBš;BuBAçB
+ŸBÛB"škB%uAB(BB+îB-ÛÄB0šB3uqB6BGB9
+B;ÛôB>šÊBAu¡BDBwBGMBIÜ$BLšúBOuÐBRB§BU}BWÜSBZ©*B]v B`BÖBc­BeÜBh©ZBkv0BnCBqÝBsÜ³Bv©Byv`B|C6B|^z¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A!AaA
+fA(Ç¿A3ûA?.pAJaÈAU!A`ÈyAkûÑAw/*A1BAÊîAdAþHAõA1¢A¢ËNAšdûA­þ§A³TA¹2AŸË­AÄeZAÉÿAÏ³AÕ2aAÚÌAàeºAåÿgAëAñ2ÀAöÌmAüfB ÿãBÌ¹BB	ffB
+3<B BÌéB¿BfB3mB
+ CBÍB"ðB%fÆB(3B+ sB-ÍIB0B3föB63ÌB9 ¢B;ÍyB>OBAg%BD3üBG ÒBIÍšBLBOgUBR4+BUBWÍØBZ®B]g
+B`4\Bc2BeÎBhßBkgµBn4BqbBsÎ8BvBygåB|4»B|Oÿ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  @àã@÷ÞAóÇA' A
+ZxA(ÑA3Á)A>ôAJ'ÚAU[2A`AkÁäAvõ<AJA­÷AG€AáQAzýAªA¢®VAšHA­á°A³{\A¹	AŸ®¶AÄHbAÉâAÏ{œAÕiAÚ¯AàHÂAåâoAë|
+AñÈAö¯uAüI"B ñgBŸ=BB	WêB
+$ÀBñBŸmBDBXB$ðB
+ñÇBŸB"sB%XJB(% B*ñöB-ŸÍB0£B3XyB6%PB8ò&B;ŸüB>ÓBAX©BD%BFòVBI¿,BLBOXÙBR%¯BTò
+BW¿\BZ3B]Y	B`%ßBbò¶Be¿BhbBkY9Bn&BpòåBs¿ŒBvByYiB|&?B|A¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  @³¡È@Ê?¢@àŠS@÷
+A¹ÚAí3A
+ A(SäA3<A>ºAIííAU!FA`TAköAv»OA÷TAA*­AÄZA^A÷³A¢`Aš+
+A­Ä¹A³^fAžøAŸÀAÄ+mAÉÅAÏ^ÆAÔørAÚAà+ÌAåÅxAë_%AðøÒAö~Aü,+B âëB¯ÂB|B	InB
+EBã
+B¯òB|ÈBIBuB
+ãKB°"B"|øB%IÎB(¥B*ã{B-°QB0}(B3IþB6ÕB8ã«B;°B>}WBAJ.BDBFãÚBI°±BL}BOJ]BR4BTä
+BW°áBZ}·B]JB`dBbä:Be±Bh}çBkJœBnBpäjBs±ABv~ByJíB|ÄB|3¿  ¿  ¿  ¿  ¿  ¿  @`@þe@³e@ÉËÇ@à2x@ö)AíA³FA
+æA(öA3MOA>šAIŽ ATçXA`±AkN	AvbAÚ]At
+A
+·A§cAAAÚŒA¢tiAšA­§ÂA³ApAžÛ
+AŸtÉAÄvAÉš"AÏAÏAÔÛ|AÚu(AàÕAåšAëB.AðÛÛAöuAü5B ÔpB¡FBn
+B	:ôB
+ÊBÔ B¡wBnMB;#BúB
+ÔÐB¡ŠB"n}B%;SB()B*Õ B-¡ÖB0n­B3;B6YB8Õ/B;¢B>nÜBA;²BDBFÕ_BI¢5BLo
+BO;ãBR¹BTÕBW¢fBZo<B]<B`éBbÕ¿Be¢BholBk<BBn	BpÕïBs¢ÅBvoBy<rB|	HB|$¿  ¿  ¿  ¿  @2>@_zS@#Ú@@²ñ<@ÉWì@ßŸ@ö%OAF AyXA
+¬±A'à
+A3bA>FºAIzAT­kA_àÄAk
+AvGuAœgAWAðÀAlA$AœÆA¢WrA§ñ A­ÍA³$yAžŸ&AŸWÒAÃñAÉ,AÏ$ØAÔŸ
+AÚX2AßñÞAåAë%9AðŸåAöXAûò>B ÅõBÌB_¢B	,xB
+ùOBÆ%BûB_ÒB,šBù~B
+ÆUB+B"`B%,ØB'ù®B*Æ
+B-[B0`1B3-B5ùÞB8ÆŽB;B>`aBA-7BCú
+BFÆäBI»BL`BO-gBQú>BTÇBWêBZ`ÁB]-B_úmBbÇDBeBh`ñBk-ÇBmúBpÇtBsJBva By-÷B{úÍB|¿  ¿  ?¯xI@÷Ú@1Å<@^@
+° @°@²}b@Èä@ßJÃ@õ±tA
+A?lA
+rÄA'Š
+A2ÙuA>
+ÍAI@&ATs~A_Š×AjÚ/Av
+A pA:
+AÓÉAmvA"A ÐA¢:}A§Ô)A­mÖA³Až¡/AŸ:ÜAÃÔAÉn5AÏâAÔ¡AÚ;;AßÔéAånAëBAð¡îAö;AûÕHB ·zBPBQ'B	
+ýB
+êÓB·ªBBQVB
+-BëB
+·ÙB°B"QB%
+]B'ë3B*ž	B-ßB0Q¶B3
+B5ëbB8ž9B;
+B>QåBA
+ŒBCëBFžiBI
+?BLRBO
+ìBQëÂBTžBW
+oBZREB]
+B_ëòBbžÉBe
+BhRuBkLBmì"BpžøBs
+ÏBvR¥By{B{ìQB|?!G®?)Õ?®
+@$@0Ý@]ªé@
+<%@¢×@²	@Èp8@ÞÖé@õ=AÒ&A~A
+8×A'l/A2A=ÒàAI9AT9A_léAj BAuÓAyA
+&A¶ÒAPAê-AÙA¢
+A§·2A­PßA²êAž8AŸ
+åAÃ·AÉQ>AÎêëAÔAÚ
+EAß·òAåQAêëKAðøAö
+€AûžQB šÿBuÕBB«B	B
+ÜXB©.BvBBÛB±BÜB
+©^Bv5B"C
+B%áB'Ü·B*©B-vdB0C:B3B5ÜçB8©œB;vB>CkBAABCÝBF©îBIvÄBLCBOqBQÝGBTª
+BWvôBZCÊB]¡B_ÝwBbªMBew$BhCúBkÐBmÝ§Bpª}BswSBvD)By B{ÝÖ¿  ?b(?&6¬?¬¶@(p@/õÒ@\Ã4@ÈK@.ü@±­@Çü^@Þc@ôÉÀA9AËAþêA'2BA2eA=óAHÌKASÿ€A_2üAjfUAu­AfA 0AÝA3AÍ6AfâA¢ A§<A­3èA²ÍAžgBAŸ îAÃAÉ4IAÎÍõAÔg¢AÚNAßûAå4šAêÎTAðhAö®AûZB BgZB40B	B
+ÍÝB³BgB4`B6BÎ
+B
+ãBg¹B"4B%fB'Î<B*B-géB04¿B3B5ÎlB8CB;hB>4ïBAÆBCÎBFrBIhIBL5BOõBQÎÌBT¢BWhyBZ5OB]%B_ÎüBbÒBehšBh5BkUBmÏ+BpBshØBv5®By	j¿  ¿  ?ÃV?"×?ªæ°@@º@/
+@[Û~@Tp@»!@±!Ò@Ç@Ýï3@ôUäA^KA£AÄüA&øTA2+¬A=_AH]ASÅ¶A^ùAj,gAu_¿AIA
+ã9A|æAA°?AIìA¡ãA§}EA­òA²°AžJKAœãùAÃ}¥AÉRAÎ°þAÔJ«AÙäXAß~Aå±Aê±^AðK
+Aõä·Aû~eB BXÞB%µBòB
+¿aB8BYB%åBò»B¿B
+gBY>B"&B$òêB'¿ÁB*B-YmB0&DB2óB5¿ñB8ÇB;YB>&tB@óJBCÀ!BF÷BIYÍBL&€BNózBQÀQBT'BWYýBZ&ÔB\óªB_ÀBbWBeZ-Bh'BjóÙBmÀ°BpBsaB¿  ¿  ¿  ¿  ?$?
+ù?©F@Y@.&h@ZóÊ@à@GG@°­÷@Çš@Ý{Y@óâ
+A$^AW¶AA&ŸgA1ñ¿A=%AHXpASÉA^¿!AiòyAu%ÒA,A
+ÆCA_ïAùAHA,õA¡Æ¢A§`NA¬ùûA²©Až-UAœÇAÃ`¯AÈú[AÎAÔ-ŽAÙÇaAßaAäúºAêgAð.AõÇÁAûanB }BJcB9BäB
+°æB}œBJBiBä?B±B
+}ìBJÂB"B$äoB'±EB*~
+B-JóB0ÉB2äB5±vB8~LB;K"B>ùB@äÏBC±¥BF~|BIKRBL)BNäÿBQ±ÕBT~¬BWKBZXB\å/B_²Bb~ÛBeK±BhBjå^Bm¹¿  ¿  ¿  ¿  ¿  ¿  ?
+²?Z1?§GÝ@ qQ@->³@Z
+@l»@Ól@°:
+@Æ Î@Ý@ón0AêpA
+ÉAQ!A&zA1·ÒA<ë+AH
+ASQÛA^
+4AižAtëåAA
+©LABøAÜ¥AvRAþA¡©«A§CYA¬ÝA²v²Až_Aœª
+AÃCžAÈÝdAÎwAÔŸAÙªjAßDAäÝÅAêwqAð
+AõªÊAûDwB oB;èBŸBÕB
+¢kBoAB<BîBÕÄB¢B
+oqB<GB"	
+B$ÕôB'¢ËB*o¡B-<wB0	NB2Ö$B5¢úB8oÑB;<§B>	}B@ÖTBC£*BFpBI<×BL	­BNÖBQ£ZBTp0BW=BZ	ÝB\Ö³B_£Bbp`Be=6Bhò¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ?æá?»X?¥xp?ÿ5@,Vý@Y$_@øà@_@¯ÆC@Æ,ó@Ü€@òúTA°AãÜA4A&JA1}åA<±=AGäASïA^KGAi~At±øAåQA
+UA&A¿®AY[Aó	A¡µA§&bA¬ÀA²Y»A·óhAœAÃ&ÁAÈÀnAÎZAÓóÇAÙuAß'!AäÀÎAêZzAïô'AõÔAû'B `B-mBúCBÇB
+ïB`ÆB-BúrBÇIBB
+`õB-ÌB!ú£B$ÇyB'OB*a&B--üB/úÒB2Ç©B5B8aUB;.,B=ûB@ÇÙBC¯BFa
+BI.\BKû2BNÈBQßBTaµBW.BYûaB\È8B_BbhÊ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ?
+H?
+?£©?ýCÌ@+oI@X<ª@
+@ë·@¯Rh@Å¹@ÜÊ@òzAvA©ïAÝGA&A1CøA<wQAGª©ARÞA^ZAiD²Atx
+A«dA
+o^A	
+A¢¹A<eAÖA¡o¿A§	kA¬£A²<ÄA·ÖqAœp
+AÃ	ÊAÈ£wAÎ=%AÓÖÑAÙp~Aß
+*Aä£×Aê=Aï×0AõpÝAû
+B RB
+ñBëÇBžB
+
+tBRJB!Bë÷BžÍB
+€B
+R{BQB!ì'B$žþB'
+ÔB*RªB-B/ìWB2¹-B5B8RÚB;±B=ìB@¹]BC4BFS
+BIàBKì·BN¹BQcBTS9BW BYìæB\À¢¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ?	©>?}¬?¡Ù?ût_@*@WTô@+@wÛ@®Þ@ÅE=@Û«î@òA<šAp A£YA%Ö²A1
+
+A<=bAGp»AR€A]×lAi
+ÄAt>
+AquA
+RhAìA
+ÁAnA¹A¡RÇAŠìsA¬ A²ÍA·¹yAœS&AÂìÔAÈAÎ -AÓ¹ÚAÙSAÞí3AäßAê Aïº9AõSåAúíB CBvBÝLBª"B
+vùBCÏB¥BÝ|BªSBw)B
+CÿBÖB!Ý¬B$ªB'wYB*D/B-B/ÝÜB2ª²B5wB8D_B;5B=Þ
+B@ªâBCwžBFDBIeBKÞ;BN«BQwèBTDŸBWz¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ?
+k?
+ÞÚ? 
+2?ù€ö@)Þ@Vm@@Q@@®j²@ÄÑc@Û8@ñÅA»A6AilA%ÄA0Ð
+A<uAG6ÎARj&A]AhÐ×At/A7A
+5qAÏ
+AhÊAwA#A¡5ÐAŠÏ}A¬i)A²ÖA·Aœ60AÂÏÝAÈiAÎ6AÓãAÙ6AÞÐ<AäiéAêAïBAõ6ïAúÐB 5$BúBÎÑB§B
+h}B5TB+BÏB×Bh®B
+5BZB!Ï1B$B'hÝB*5ŽB-B/ÏaB27B5i
+B85äB;ºB=ÏB@gBCi=BF6BIéBKÏÀBNBQpR¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ?k?	@?:Å?÷Õ@(ž(@U
+@)u@&@­ö×@Ä]@ÚÄ9@ñ*êAÈÎAü&A/A%b×A00A;ÉAFüáAR09A]cAhêAsÊBA~ýA
+zA²'AKÓAåA-A¡ÙAŠ²A¬L4A±åàA·Aœ:AÂ²æAÈLAÍæ?AÓìAÙAÞ³EAäLòAéæAïLAõùAú³¥B &©BóBÀUB,B
+ZB&ÙBó¯BÀB\BZ2B
+'	B
+óßB!ÀµB$B'ZbB*'9B,ôB/ÀåB2ŒB5ZB8'hB:ô?B=ÁB@ëBCZÁBF'BHônBKÈ*¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >ý?¡/?k\?ö!@'Ðs@TÕ@µ@
+L@­ý@Ãé®@ÚP_@ð·AáAÂ9AõA%(êA0\CA;AFÂóAQöLA])€Ah\ýAsUA~Ã®AûA0A.ÝAÈAb6A ûäAŠA¬/=A±ÈêA·bAŒüCAÂïAÈ/AÍÉIAÓbõAØü¢AÞOAä/üAéÉ©AïcUAôýAú¯B -BåB±ÛB~±B
+KB^Bå4B²
+B~áBK·B
+B
+ådB!²:B$B'KçB*œB,åB/²jB2@B5LB8íB:åÃB=²B@pBCLFBF ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >ö[ë?U?ï?ô6Ž@&èœ@S¶
+@AÀ@šq@­"@ÃuÓ@ÙÜ@ðC4ATóAKA»€A$îüA0"TA;U­AFAQŒ^A\ï¶Ah#AsVgA~ÀAÞAx9AæA«AE@A ÞíAŠxA¬FA±«óA·EAŒßLAÂxùAÈ¥AÍ¬RAÓEÿAØß¬AÞyYAäAé¬²AïF_Aôà
+AúyžB 	³BÖB£_Bp6B
+=
+B	âBÖ¹B£BpeB=<B
+
+B
+ÖéB!£¿B$pB'=lB*
+BB,×B/£ïB2pÅB5=B8
+qB:×HB=€
+B@wÚ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >ï
+I>üÇ?Ì?ògK@&@RÎj@Ì@4@¬G@Ãù@Ùh©@ïÏZAAN^A¶A$µA/ègA;ÀAFOAQqA\µÉAgé!As
+zA~OÓAÁA[DAôðAA(JA ÁöAŠ[£A«õOA±üA·(©AŒÂUAÂ\AÇõ¯AÍ\AÓ)	AØÂ¶AÞ\bAãöAé»Aï)hAôÃAú\ÁAÿönBÈBäBaºB
+.B
+ûgBÈ=BBaêB.ÁBûB
+ÈmB!DB$bB'.ðB)ûÇB,ÈB/sB2bIB5/ B7ûöB:Ï²¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >çà¥>õc?ý
+?ðâ@%T@Qæ¶@~Ž@Àœ@¬'m@Â
+@ØôÏ@ï[AáAqAGÉA${"A/®zA:áÓAF+AQHA\{ÜAg¯5ArâA~çA€ A>MA×úAqŠA
+SA €ÿAŠ>¬A«ØYA±rA·
+²AŒ¥_AÂ?
+AÇØ¹AÍrfAÓ
+AØ¥¿AÞ?kAãÙAérÅAï
+qAôŠ
+Aú?ËAÿÙxB¹BiBS?B
+ B
+ììB¹ÂBBSoB EBí
+B
+¹òB!ÈB$SB' uB)íKB,º!B/øB2SÎB5'¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >à£>îK ?-¬?îÈq@$1@Pþý@}Ì_@Là@«³@ÂB@Øó@îç€A§*A
+ÚA
+ÛA$A4A/tA:§äAEÛ=AQA\AîAguFAršA}ÛøA©A!UA»AT®Aî[A AŠ!ŽA«»aA±UA¶î»AŒhAÂ"AÇ»ÁAÍUnAÒïAØÇAÞ"tAãŒ AéUÍAîïzAô&Aú"ÔAÿŒB«BwìBDÃB
+B
+ÞpB«FBx
+BDóBÉBÞB
+«vB!xLB$E"B'øB)ÞÏB,«¥B/a¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >Ùe]>ç
+û?^C?ìù@#Iç@PH@|äª@Ù@«?·@ÁŠh@Ø
+@îsÊAm=A
+ AÓîA$FA/:A:møAE¡PAPÔšA\Ag;YArn²A}¢
+Aj²A^A
+A7žAÑdA kAŠŸA«kA±8A¶ÑÅAŒkqAÂ
+AÇÊAÍ8wAÒÒ$AØkÐAÞ}Aã*Aé8ÖAîÒAôl1AúÝAÿBBiqB6HB
+
+B
+ÏôBËBi¡B6wBNBÐ$B
+úB!iÐB$6§B'}B)×9¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >Ò'»>ßÐY?Û?ë)@"b3@O/@{üö@e,@ªËÝ@Á2@×?@íÿïA3PA
+fšAA#ÍZA/ ²A:4
+AEgcAP»A[ÎAglAr4ÅA}h
+AM»AçhAAÁAŽnA NA¥çÈA«uA±!A¶ŽÎAŒNzAÁè'AÇÔAÍAÒµ-AØNÚAÝèAã4AéáAîµAôO:AùèæAÿB BZöB'ÌB
+ô£B
+ÁyBOB[&B'üBôÒBÁšB
+B![UB$/¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >Êê>Øµ?¿r?éZ6@!z~@NGà@{A@ñR@ªX@ÀŸ³@×%d@íAùcA
+,ŒA`A#lA.ÆÅA9ú
+AE-vAP`ÎA['AfÇAqú×A}./A0ÄAÊqAd
+AýËAxA 1%A¥ÊÑA«d~A°þ*A¶×AŒ1AÁË0AÇdÝAÌþAÒ7AØ1äAÝËAãe=AèþêAîAô2CAùËðAÿeB€BL{BQB
+æ'B
+²þBÔBLªBBæWB³-B
+é¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >Ã¬s>ÑTñ?ð?çÆ@ Å@M`'@z-@}u@©ä&@ÀJ×@Ö±@í9A¿uA
+òÍA&&A#Y~A.×A9À/ADóAP&àA[Z8AfAqÀéA|ôBAÎA­{AG(AàÕAzA .A¥­ÚA«GA°á4A¶zàAŒAÁ®:AÇGçAÌáAÒ{AAØíAÝ®AãHFAèáóAî{ AôLAù®ùAÿH¥Bq)B=ÿB
+ÖB
+×¬B
+€BqXB>/B
+BÞÁ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >ŒnÐ>ÊN? ?å»\@«@Lxr@yEÔ@	@©pL@¿Öý@Ö=®@ì€_A
+A
+žàAì9A#A.RêA9BAD¹AOìòA[ KAfS€AqüA|ºUAöØA
+A*1AÃÞA]A÷7A¥äA«*A°Ä=A¶]êA»÷AÁDAÇ*ñAÌÄAÒ^JA×÷öAÝ£Aã+PAèÄüAî^©AóøVAùAÿ+¯Bb®B/BüZB
+É0B
+BbÝB6¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >µ1,>ÂÙª?Q/?ãëó@
+Ã\@KŸ@x^ @Á@šür@¿c#@ÕÉÔ@ì0
+AKA
+~óA²LA"å€A.üA9LTAD­AO³AZæ^Af·AqMA|iAÙáAsA
+:AŠçA@AÚ@A¥síA«
+A°§GA¶@ôA»Ú¡AÁtMAÇ
+úAÌ§ŠAÒASA×Û AÝt¬AãYAèšAîA²AóÛ`Aùu
+Aÿ·BT2B!BíßB
+ºµB
+q¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >­ó>»?Æ?â
+@
+Ûš@J©
+@wvl@!ç@š@ŸïI@ÕUù@ëŒ«A®A
+EAx^A"«¶A-ßA9hADEÀAOyAZ¬qAeßÉAq"A|F|AŒêAVAðDAðA#AœJA¥V÷Aªð€A°QA¶#ýA»œªAÁWVAÆñAÌ°AÒ$\A×Ÿ	AÝW¶AâñbAèAî$œAóŸiAùXAþñÁBE·BBæI¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >Šµå>Ž^C?²U?àM@
+óï@IÁQ@v³@®
+@š»@Ÿ{m@Ôâ
+@ëHÎA ×¿A
+
+A>pA"qÉA-¥!A8ØzAD
+ÒAO?*AZrAe¥ÜApÙ4A|
+AóA9AÓLAlùAŠA SA¥: AªÓ¬A°mYA¶A» ²AÁ:_AÆÔ
+AÌmžAÒeA×¡AÝ:¿AâÔlAènAîÅAó¡rAù;
+AþÔËB>!¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >xA>­ À?âô?Þ}¹@
+
+?@HÙ¡@u§@:3@§ ã@Ÿ@ÔnD@êÔöA ÓA
+Ñ,AA"7ÝA-k5A8ACÑæAO?AZ8AekïApGA{Ò¡AýA
+ªA¶WAPAé±A]A¥
+
+Aª¶¶A°PcAµêA»ŒAÁ
+iAÆ·AÌPÂAÑêpA×
+AÝ
+ÉAâ·vAèQ#AíêÏAó|Aù+ó¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >:>¥ã??Ü®P@$@Gñì@t¿N@ÆX@§-@œº@Óúk@êaA cæA
+?AÊA!ýïA-1HA8d¡ACùANËQAYþ©Ae2Ape[A{ŽAfAÿŽAaA3
+AÌºAffA¥ AªÀA°3lAµÍA»fÆAÁ rAÆ AÌ3ÍAÑÍyA×g&AÝ ÓAâAè4,AíÛ£¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >üú>¥x?D"?ÚÞç@<Ö@G
+8@s×@R~@Š¹/@œß@Ó@éíAA )ùA
+]QAªA!ÄA,÷[A8*³AC^
+ANdAYÄœAdøAp+nA{^ÇAIAâœA|jAA¯ÃAIpA€ã
+Aª|ÉA°vAµ°"A»IÐAÀã}AÆ})AÌÖAÑ°A×J/AÜãÜAâS¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >¿W>h?~é?Ù@U*@F"@rïí@Þ§@ŠEX@Œ¬	@Óº@éyk@ÿà
+A
+#gAV¿A!A,œpA7ðÈAC$!ANWyAYÒAdŸ*AoñA{$ÜA,AÅÈA_tAù!AÍA,zA€Æ'Aª_ÓA¯ùAµ.A»,ÚAÀÆAÆ`4AËùàAÑA×;¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >³>*q?{JÂ?×@%@mv@E:×@r9@jÍ@¥Ñ~@Œ8/@Òà@é@ÿlBA
+éyA
+ÒA!P*A,A7¶ÛABê4AN
+AYPäAd=Ao·AzêïA$AšÑAB}AÜ*Au×AA€©1AªBÞA¯ÜAµv7A»äAÀ©AÆC=AËêŽ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >v
+>ìÍ?w«ð?Õpœ@
+Á@DS#@q @öó@¥]€@»ÄU@Ò+@è¶@þøgA
+¯AâåA!=A,IA7|îAB°FAMãAYøAdJPAo}šAz±Aò-AÚA%A¿3AXáAòA€:Aª%çA¯¿AµY@AºòíAÀd¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >h
+×>¯j?t
+>?Ó¡d@@Ckv@p8Ø@
+@€éÎ@»P~@Ñ·/@è
+à@þA
+u¡AšúA ÜRA,ªA7CABv\AM©ŽAXÝ
+AdeAoCœAzwAÕ8AnäAA¢?A;ëAÕA€oEAªñA¯¢AµJ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >Y>tã?pnm?ÑÑû@¶`@BÂ@oQ$@C@€uó@ºÜ¥@ÑCU@çª@þ·A
+;ŽAo
+A ¢eA+ÕŸA7	AB<nAMoÇAX£AcÖxAo	ÐAz=)AžBAQïAëA
+HA
+õAž¡A€RNA©ùÅ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >KJ>fhÆ?lÏ»?Ð¢@ÎŽ@A@niw@m@€
+@ºhÎ@ÐÏ@ç60@ýáA
+ÉA5"A hzA+ÒA6Ï+ABAM5ÜAXi4AcAnÏåAz?ALA4ùAÎŠAhRAÿA©v¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ><>Wí?i0è?Î39@ç @@Ža@mÃ@'@£C@¹ôô@Ð[¥@æÂV@ý)A	ÇÜAû4A .A+aåA6>AAÈALûïAX/GAcbAnøAyÉRA~VAA±¯AY&¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >.»>Ir7?e?ÌcÐ@ÿK@?Ì­@l@³ž@£i@¹@ÏçË@æN|@üµ-A	ïAÁGAô A+'øA6[QAA©ALÂAWõZAc(³An\
+AydAa_AÖ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >€s>:÷p?aóe?Êx@@>å @k²b@?â@¢Š@¹
+D@Ïsõ@åÚ¥@üAVA	TA\AºµA*î
+A6!eAATŸALAW»oAbîÇAn" Ayq¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >)/>,|,?^T?ÈÅ@/ê@=ýL@jÊ­@Ì@¢2¹@žj@Ï @åfË@ûÍ}A	AMoAÇA*Ž A5çyAAÑALN)AWAbÐo¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >­é>
+ æ?ZµÃ?ÆõŠ@H5@=@iâù@X.@¡Ÿß@ž%@Î@@äòò@ûY¢Aà)AAFÛA*z3A5­A@àäAL/Ñ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  =èeE>?W?Å&M@`@<-ë@hûM@äW@¡K@·±º@Îj@ä@úåÌAŠ?AÙA
+ïA*@HA55¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  =Ën¹>
+Ù?Sx@?ÃVä@xÕ@;F7@h@p~@ ×.@·=ß@Í€@ä
+A@úqòAlQAªA
+î¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  =®x1=å *?OÙ?Á@
+(@:^@g+ì@ü§@ cX@¶Ê	@Í0º@ãk@ùþ
+AMû¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  =€=È)?L:Œ?¿ž#@
+©t@9vÖ@fD8@Í@ï~@¶V/@ÌŒà@ãZº¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  =i.=«3?Hë?œèº@
+ÁÀ@8"@e\@ó@{€@¶~¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  =/)==?Dý9?Œa@
+Ú@7§u@dt×@ØF¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  <êwô=bì?A^h?ºIù@	ò_@7.¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  <m;Š=( Ü?=¿?¹W6¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  9°ç\=
+J¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                  -32 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   64 / length of data axis 1                          NAXIS2  =                   64 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ?!G®?Ð£×@(Qì@hQì@(ö@Ž(ö@Ô(ö@ô(öA
+{A{A*{A:{AJ{AZ{Aj{Az{A
+
+=A
+=A
+=A
+=A¥
+=A­
+=Aµ
+=Aœ
+=AÅ
+=AÍ
+=AÕ
+=AÝ
+=Aå
+=Aí
+=Aõ
+=Aý
+=B
+B
+B
+
+B
+B
+B
+B
+B
+
+B"
+B&
+B*
+B.
+B2
+B6
+B:
+B>
+BB
+BF
+BJ
+BN
+BR
+BV
+BZ
+B^
+Bb
+Bf
+Bj
+Bn
+Br
+Bv
+Bz
+B~
+?
+žR?Ï\)@'®@g®@×
+@³×
+@Ó×
+@ó×
+A	ë
+Aë
+A)ë
+A9ë
+AIë
+AYë
+Aië
+Ayë
+AõÃAõÃAõÃAõÃA€õÃA¬õÃAŽõÃAŒõÃAÄõÃAÌõÃAÔõÃAÜõÃAäõÃAìõÃAôõÃAüõÃBzáBzáB
+záBzáBzáBzáBzáB
+záB"záB&záB*záB.záB2záB6záB:záB>záBBzáBFzáBJzáBNzáBRzáBVzáBZzáB^záBbzáBfzáBjzáBnzáBrzáBvzáBzzáB~zá?
+(ö?Î{@'
+>@g
+>@
+@³
+@Ó
+@ó
+A	ÂAÂA)ÂA9ÂAIÂAYÂAiÂAyÂAáHAáHAáHAáHA€áHA¬áHAŽáHAŒáHAÄáHAÌáHAÔáHAÜáHAäáHAìáHAôáHAüáHBp€Bp€B
+p€Bp€Bp€Bp€Bp€B
+p€B"p€B&p€B*p€B.p€B2p€B6p€B:p€B>p€BBp€BFp€BJp€BNp€BRp€BVp€BZp€B^p€Bbp€Bfp€Bjp€Bnp€Brp€Bvp€Bzp€B~p€??ÌÌÍ@&ff@fff@33@³33@Ó33@ó33A	AA)A9AIAYAiAyAÌÍAÌÍAÌÍAÌÍA€ÌÍA¬ÌÍAŽÌÍAŒÌÍAÄÌÍAÌÌÍAÔÌÍAÜÌÍAäÌÍAìÌÍAôÌÍAüÌÍBffBffB
+ffBffBffBffBffB
+ffB"ffB&ffB*ffB.ffB2ffB6ffB:ffB>ffBBffBFffBJffBNffBRffBVffBZffB^ffBbffBfffBjffBnffBrffBvffBzffB~ff?
+=?Ë
+
+@%Â@eÂ@áH@²áH@ÒáH@òáHA	p€Ap€A)p€A9p€AIp€AYp€Aip€Ayp€AžRAžRAžRAžRA€žRA¬žRAŽžRAŒžRAÄžRAÌžRAÔžRAÜžRAäžRAìžRAôžRAüžRB\)B\)B
+\)B\)B\)B\)B\)B
+\)B"\)B&\)B*\)B.\)B2\)B6\)B:\)B>\)BB\)BF\)BJ\)BN\)BR\)BV\)BZ\)B^\)Bb\)Bf\)Bj\)Bn\)Br\)Bv\)Bz\)B~\)?zá?Ê=p@%
+ž@e
+ž@\@²\@Ò\@ò\A	G®AG®A)G®A9G®AIG®AYG®AiG®AyG®A£×A£×A£×A£×A€£×A¬£×AŽ£×AŒ£×AÄ£×AÌ£×AÔ£×AÜ£×Aä£×Aì£×Aô£×Aü£×BQìBQìB
+QìBQìBQìBQìBQìB
+QìB"QìB&QìB*QìB.QìB2QìB6QìB:QìB>QìBBQìBFQìBJQìBNQìBRQìBVQìBZQìB^QìBbQìBfQìBjQìBnQìBrQìBvQìBzQìB~Qì?ë
+?ÈõÂ@$zá@dzá@=q@²=q@Ò=q@ò=qA	
+žA
+žA)
+žA9
+žAI
+žAY
+žAi
+žAy
+žA\A\A\A\A€\A¬\AŽ\AŒ\AÄ\AÌ\AÔ\AÜ\Aä\Aì\Aô\Aü\BG®BG®B
+G®BG®BG®BG®BG®B
+G®B"G®B&G®B*G®B.G®B2G®B6G®B:G®B>G®BBG®BFG®BJG®BNG®BRG®BVG®BZG®B^G®BbG®BfG®BjG®BnG®BrG®BvG®BzG®B~G®?\)?Ç®@#×
+@c×
+@ë
+@±ë
+@Ñë
+@ñë
+AõÃAõÃA(õÃA8õÃAHõÃAXõÃAhõÃAxõÃAzáAzáAzáAzáA€záA¬záAŽzáAŒzáAÄzáAÌzáAÔzáAÜzáAäzáAìzáAôzáAüzáB=qB=qB
+=qB=qB=qB=qB=qB
+=qB"=qB&=qB*=qB.=qB2=qB6=qB:=qB>=qBB=qBF=qBJ=qBN=qBR=qBV=qBZ=qB^=qBb=qBf=qBj=qBn=qBr=qBv=qBz=qB~=q?
+ÌÍ?Æff@#33@c33@@±@Ñ@ñAÌÍAÌÍA(ÌÍA8ÌÍAHÌÍAXÌÍAhÌÍAxÌÍAffAffAffAffA€ffA¬ffAŽffAŒffAÄffAÌffAÔffAÜffAäffAìffAôffAüffB33B33B
+33B33B33B33B33B
+33B"33B&33B*33B.33B233B633B:33B>33BB33BF33BJ33BN33BR33BV33BZ33B^33Bb33Bf33Bj33Bn33Br33Bv33Bz33B~33?
+=q?Å
+ž@"\@b\@G®@±G®@ÑG®@ñG®A£×A£×A(£×A8£×AH£×AX£×Ah£×Ax£×AQìAQìAQìAQìA€QìA¬QìAŽQìAŒQìAÄQìAÌQìAÔQìAÜQìAäQìAìQìAôQìAüQìB(öB(öB
+(öB(öB(öB(öB(öB
+(öB"(öB&(öB*(öB.(öB2(öB6(öB:(öB>(öBB(öBF(öBJ(öBN(öBR(öBV(öBZ(öB^(öBb(öBf(öBj(öBn(öBr(öBv(öBz(öB~(ö?®?Ã×
+@!ë
+@aë
+@õÂ@°õÂ@ÐõÂ@ðõÂAzáAzáA(záA8záAHzáAXzáAhzáAxzáA=qA=qA=qA=qA€=qA¬=qAŽ=qAŒ=qAÄ=qAÌ=qAÔ=qAÜ=qAä=qAì=qAô=qAü=qB
+žB
+žB
+
+žB
+žB
+žB
+žB
+žB
+
+žB"
+žB&
+žB*
+žB.
+žB2
+žB6
+žB:
+žB>
+žBB
+žBF
+žBJ
+žBN
+žBR
+žBV
+žBZ
+žB^
+žBb
+žBf
+žBj
+žBn
+žBr
+žBv
+žBz
+žB~
+ž?
+ž?Â\@!G®@aG®@£×@°£×@Ð£×@ð£×AQìAQìA(QìA8QìAHQìAXQìAhQìAxQìA(öA(öA(öA(öA€(öA¬(öAŽ(öAŒ(öAÄ(öAÌ(öAÔ(öAÜ(öAä(öAì(öAô(öAü(öB{B{B
+{B{B{B{B{B
+{B"{B&{B*{B.{B2{B6{B:{B>{BB{BF{BJ{BN{BR{BV{BZ{B^{Bb{Bf{Bj{Bn{Br{Bv{Bz{B~{?\?ÁG®@ £×@`£×@Qì@°Qì@ÐQì@ðQìA(öA(öA((öA8(öAH(öAX(öAh(öAx(öA{A{A{A{A€{A¬{AŽ{AŒ{AÄ{AÌ{AÔ{AÜ{Aä{Aì{Aô{Aü{B
+=B
+=B
+
+=B
+=B
+=B
+=B
+=B
+
+=B"
+=B&
+=B*
+=B.
+=B2
+=B6
+=B:
+=B>
+=BB
+=BF
+=BJ
+=BN
+=BR
+=BV
+=BZ
+=B^
+=Bb
+=Bf
+=Bj
+=Bn
+=Br
+=Bv
+=Bz
+=B~
+=?   ?À  @   @`  @  @°  @Ð  @ð  A  A  A(  A8  AH  AX  Ah  Ax  A  A  A  A  A€  A¬  AŽ  AŒ  AÄ  AÌ  AÔ  AÜ  Aä  Aì  Aô  Aü  B  B  B
+  B  B  B  B  B
+  B"  B&  B*  B.  B2  B6  B:  B>  BB  BF  BJ  BN  BR  BV  BZ  B^  Bb  Bf  Bj  Bn  Br  Bv  Bz  B~  >úáH?ŸžR@\)@_\)@®@¯®@Ï®@ï®A×
+A×
+A'×
+A7×
+AG×
+AW×
+Ag×
+Aw×
+Aë
+Aë
+Aë
+Aë
+A£ë
+A«ë
+A³ë
+A»ë
+AÃë
+AËë
+AÓë
+AÛë
+Aãë
+Aëë
+Aóë
+Aûë
+BõÃBõÃB	õÃB
+õÃBõÃBõÃBõÃB
+õÃB!õÃB%õÃB)õÃB-õÃB1õÃB5õÃB9õÃB=õÃBAõÃBEõÃBIõÃBMõÃBQõÃBUõÃBYõÃB]õÃBaõÃBeõÃBiõÃBmõÃBqõÃBuõÃByõÃB}õÃ>õÂ?œp€@
+žR@^žR@\)@¯\)@Ï\)@ï\)A®A®A'®A7®AG®AW®Ag®Aw®A×
+A×
+A×
+A×
+A£×
+A«×
+A³×
+A»×
+AÃ×
+AË×
+AÓ×
+AÛ×
+Aã×
+Aë×
+Aó×
+Aû×
+Bë
+Bë
+B	ë
+B
+ë
+Bë
+Bë
+Bë
+B
+ë
+B!ë
+B%ë
+B)ë
+B-ë
+B1ë
+B5ë
+B9ë
+B=ë
+BAë
+BEë
+BIë
+BMë
+BQë
+BUë
+BYë
+B]ë
+Baë
+Beë
+Bië
+Bmë
+Bqë
+Buë
+Byë
+B}ë
+>ð£×?Œ(ö@
+{@^{@
+=@¯
+=@Ï
+=@ï
+=A
+A
+A'
+A7
+AG
+AW
+Ag
+Aw
+AÂAÂAÂAÂA£ÂA«ÂA³ÂA»ÂAÃÂAËÂAÓÂAÛÂAãÂAëÂAóÂAûÂBáHBáHB	áHB
+áHBáHBáHBáHB
+áHB!áHB%áHB)áHB-áHB1áHB5áHB9áHB=áHBAáHBEáHBIáHBMáHBQáHBUáHBYáHB]áHBaáHBeáHBiáHBmáHBqáHBuáHByáHB}áH>ë
+?ºáH@
+p€@]p€@žR@®žR@ÎžR@îžRA\)A\)A'\)A7\)AG\)AW\)Ag\)Aw\)A®A®A®A®A£®A«®A³®A»®AÃ®AË®AÓ®AÛ®Aã®Aë®Aó®Aû®B×
+B×
+B	×
+B
+×
+B×
+B×
+B×
+B
+×
+B!×
+B%×
+B)×
+B-×
+B1×
+B5×
+B9×
+B=×
+BA×
+BE×
+BI×
+BM×
+BQ×
+BU×
+BY×
+B]×
+Ba×
+Be×
+Bi×
+Bm×
+Bq×
+Bu×
+By×
+B}×
+>æff?¹@
+ÌÍ@\ÌÍ@ff@®ff@Îff@îffA33A33A'33A733AG33AW33Ag33Aw33AAAAA£A«A³A»AÃAËAÓAÛAãAëAóAûBÌÍBÌÍB	ÌÍB
+ÌÍBÌÍBÌÍBÌÍB
+ÌÍB!ÌÍB%ÌÍB)ÌÍB-ÌÍB1ÌÍB5ÌÍB9ÌÍB=ÌÍBAÌÍBEÌÍBIÌÍBMÌÍBQÌÍBUÌÍBYÌÍB]ÌÍBaÌÍBeÌÍBiÌÍBmÌÍBqÌÍBuÌÍByÌÍB}ÌÍ>áG®?žQì@
+(ö@\(ö@{@®{@Î{@î{A
+=A
+=A'
+=A7
+=AG
+=AW
+=Ag
+=Aw
+=A
+A
+A
+A
+A£
+A«
+A³
+A»
+AÃ
+AË
+AÓ
+AÛ
+Aã
+Aë
+Aó
+Aû
+BÂBÂB	ÂB
+ÂBÂBÂBÂB
+ÂB!ÂB%ÂB)ÂB-ÂB1ÂB5ÂB9ÂB=ÂBAÂBEÂBIÂBMÂBQÂBUÂBYÂB]ÂBaÂBeÂBiÂBmÂBqÂBuÂByÂB}Â>Ü(ö?·
+>@
+@[
+@Â@­Â@ÍÂ@íÂAáHAáHA&áHA6áHAFáHAVáHAfáHAváHAp€Ap€Ap€Ap€A£p€A«p€A³p€A»p€AÃp€AËp€AÓp€AÛp€Aãp€Aëp€Aóp€Aûp€BžRBžRB	žRB
+žRBžRBžRBžRB
+žRB!žRB%žRB)žRB-žRB1žRB5žRB9žRB=žRBAžRBEžRBIžRBMžRBQžRBUžRBYžRB]žRBažRBežRBižRBmžRBqžRBužRByžRB}žR>×
+=?µÂ@áH@ZáH@p€@­p€@Íp€@íp€AžRAžRA&žRA6žRAFžRAVžRAfžRAvžRA\)A\)A\)A\)A£\)A«\)A³\)A»\)AÃ\)AË\)AÓ\)AÛ\)Aã\)Aë\)Aó\)Aû\)B®B®B	®B
+®B®B®B®B
+®B!®B%®B)®B-®B1®B5®B9®B=®BA®BE®BI®BM®BQ®BU®BY®B]®Ba®Be®Bi®Bm®Bq®Bu®By®B}®>Ñë
+?Žzá@=q@Z=q@
+ž@­
+ž@Í
+ž@í
+žA\A\A&\A6\AF\AV\Af\Av\AG®AG®AG®AG®A£G®A«G®A³G®A»G®AÃG®AËG®AÓG®AÛG®AãG®AëG®AóG®AûG®B£×B£×B	£×B
+£×B£×B£×B£×B
+£×B!£×B%£×B)£×B-£×B1£×B5£×B9£×B=£×BA£×BE£×BI£×BM£×BQ£×BU£×BY£×B]£×Ba£×Be£×Bi£×Bm£×Bq£×Bu£×By£×B}£×>ÌÌÍ?³33@@Y@ÌÍ@¬ÌÍ@ÌÌÍ@ìÌÍAffAffA&ffA6ffAFffAVffAfffAvffA33A33A33A33A£33A«33A³33A»33AÃ33AË33AÓ33AÛ33Aã33Aë33Aó33Aû33BBB	B
+BBBB
+B!B%B)B-B1B5B9B=BABEBIBMBQBUBYB]BaBeBiBmBqBuByB}>Ç®?±ë
+@õÂ@XõÂ@zá@¬zá@Ìzá@ìzáA=qA=qA&=qA6=qAF=qAV=qAf=qAv=qA
+žA
+žA
+žA
+žA£
+žA«
+žA³
+žA»
+žAÃ
+žAË
+žAÓ
+žAÛ
+žAã
+žAë
+žAó
+žAû
+žB\B\B	\B
+\B\B\B\B
+\B!\B%\B)\B-\B1\B5\B9\B=\BA\BE\BI\BM\BQ\BU\BY\B]\Ba\Be\Bi\Bm\Bq\Bu\By\B}\>Â\?°£×@Qì@XQì@(ö@¬(ö@Ì(ö@ì(öA{A{A&{A6{AF{AV{Af{Av{A
+=A
+=A
+=A
+=A£
+=A«
+=A³
+=A»
+=AÃ
+=AË
+=AÓ
+=AÛ
+=Aã
+=Aë
+=Aó
+=Aû
+=B
+B
+B	
+B
+
+B
+B
+B
+B
+
+B!
+B%
+B)
+B-
+B1
+B5
+B9
+B=
+BA
+BE
+BI
+BM
+BQ
+BU
+BY
+B]
+Ba
+Be
+Bi
+Bm
+Bq
+Bu
+By
+B}
+>œp€?¯\)@®@W®@×
+@«×
+@Ë×
+@ë×
+Aë
+Aë
+A%ë
+A5ë
+AEë
+AUë
+Aeë
+Auë
+AõÃAõÃAõÃAõÃA¢õÃAªõÃA²õÃAºõÃAÂõÃAÊõÃAÒõÃAÚõÃAâõÃAêõÃAòõÃAúõÃBzáBzáB	záB
+záBzáBzáBzáB
+záB!záB%záB)záB-záB1záB5záB9záB=záBAzáBEzáBIzáBMzáBQzáBUzáBYzáB]záBazáBezáBizáBmzáBqzáBuzáByzáB}zá>žQì?®{@
+>@W
+>@
+@«
+@Ë
+@ë
+AÂAÂA%ÂA5ÂAEÂAUÂAeÂAuÂAáHAáHAáHAáHA¢áHAªáHA²áHAºáHAÂáHAÊáHAÒáHAÚáHAâáHAêáHAòáHAúáHBp€Bp€B	p€B
+p€Bp€Bp€Bp€B
+p€B!p€B%p€B)p€B-p€B1p€B5p€B9p€B=p€BAp€BEp€BIp€BMp€BQp€BUp€BYp€B]p€Bap€Bep€Bip€Bmp€Bqp€Bup€Byp€B}p€>³33?¬ÌÍ@ff@Vff@33@«33@Ë33@ë33AAA%A5AEAUAeAuAÌÍAÌÍAÌÍAÌÍA¢ÌÍAªÌÍA²ÌÍAºÌÍAÂÌÍAÊÌÍAÒÌÍAÚÌÍAâÌÍAêÌÍAòÌÍAúÌÍBffBffB	ffB
+ffBffBffBffB
+ffB!ffB%ffB)ffB-ffB1ffB5ffB9ffB=ffBAffBEffBIffBMffBQffBUffBYffB]ffBaffBeffBiffBmffBqffBuffByffB}ff>®{?«
+@Â@UÂ@áH@ªáH@ÊáH@êáHAp€Ap€A%p€A5p€AEp€AUp€Aep€Aup€AžRAžRAžRAžRA¢žRAªžRA²žRAºžRAÂžRAÊžRAÒžRAÚžRAâžRAêžRAòžRAúžRB\)B\)B	\)B
+\)B\)B\)B\)B
+\)B!\)B%\)B)\)B-\)B1\)B5\)B9\)B=\)BA\)BE\)BI\)BM\)BQ\)BU\)BY\)B]\)Ba\)Be\)Bi\)Bm\)Bq\)Bu\)By\)B}\)>šõÃ?ª=q@
+ž@U
+ž@\@ª\@Ê\@ê\AG®AG®A%G®A5G®AEG®AUG®AeG®AuG®A£×A£×A£×A£×A¢£×Aª£×A²£×Aº£×AÂ£×AÊ£×AÒ£×AÚ£×Aâ£×Aê£×Aò£×Aú£×BQìBQìB	QìB
+QìBQìBQìBQìB
+QìB!QìB%QìB)QìB-QìB1QìB5QìB9QìB=QìBAQìBEQìBIQìBMQìBQQìBUQìBYQìB]QìBaQìBeQìBiQìBmQìBqQìBuQìByQìB}Qì>£×
+?šõÂ@zá@Tzá@=q@ª=q@Ê=q@ê=qA
+žA
+žA%
+žA5
+žAE
+žAU
+žAe
+žAu
+žA\A\A\A\A¢\Aª\A²\Aº\AÂ\AÊ\AÒ\AÚ\Aâ\Aê\Aò\Aú\BG®BG®B	G®B
+G®BG®BG®BG®B
+G®B!G®B%G®B)G®B-G®B1G®B5G®B9G®B=G®BAG®BEG®BIG®BMG®BQG®BUG®BYG®B]G®BaG®BeG®BiG®BmG®BqG®BuG®ByG®B}G®>žR?§®@×
+@S×
+@ë
+@©ë
+@Éë
+@éë
+AõÃAõÃA$õÃA4õÃADõÃATõÃAdõÃAtõÃAzáAzáAzáAzáA¢záAªzáA²záAºzáAÂzáAÊzáAÒzáAÚzáAâzáAêzáAòzáAúzáB=qB=qB	=qB
+=qB=qB=qB=qB
+=qB!=qB%=qB)=qB-=qB1=qB5=qB9=qB==qBA=qBE=qBI=qBM=qBQ=qBU=qBY=qB]=qBa=qBe=qBi=qBm=qBq=qBu=qBy=qB}=q>?Šff@33@S33@@©@É@éAÌÍAÌÍA$ÌÍA4ÌÍADÌÍATÌÍAdÌÍAtÌÍAffAffAffAffA¢ffAªffA²ffAºffAÂffAÊffAÒffAÚffAâffAêffAòffAúffB33B33B	33B
+33B33B33B33B
+33B!33B%33B)33B-33B133B533B933B=33BA33BE33BI33BM33BQ33BU33BY33B]33Ba33Be33Bi33Bm33Bq33Bu33By33B}33>zá?¥
+ž@\@R\@G®@©G®@ÉG®@éG®A£×A£×A$£×A4£×AD£×AT£×Ad£×At£×AQìAQìAQìAQìA¢QìAªQìA²QìAºQìAÂQìAÊQìAÒQìAÚQìAâQìAêQìAòQìAúQìB(öB(öB	(öB
+(öB(öB(öB(öB
+(öB!(öB%(öB)(öB-(öB1(öB5(öB9(öB=(öBA(öBE(öBI(öBM(öBQ(öBU(öBY(öB](öBa(öBe(öBi(öBm(öBq(öBu(öBy(öB}(ö>\)?£×
+@ë
+@Që
+@õÃ@šõÃ@ÈõÃ@èõÃAzáAzáA$záA4záADzáATzáAdzáAtzáA=qA=qA=qA=qA¢=qAª=qA²=qAº=qAÂ=qAÊ=qAÒ=qAÚ=qAâ=qAê=qAò=qAú=qB
+žB
+žB	
+žB
+
+žB
+žB
+žB
+žB
+
+žB!
+žB%
+žB)
+žB-
+žB1
+žB5
+žB9
+žB=
+žBA
+žBE
+žBI
+žBM
+žBQ
+žBU
+žBY
+žB]
+žBa
+žBe
+žBi
+žBm
+žBq
+žBu
+žBy
+žB}
+ž>=q?¢\@G®@QG®@£×@š£×@È£×@è£×AQìAQìA$QìA4QìADQìATQìAdQìAtQìA(öA(öA(öA(öA¢(öAª(öA²(öAº(öAÂ(öAÊ(öAÒ(öAÚ(öAâ(öAê(öAò(öAú(öB{B{B	{B
+{B{B{B{B
+{B!{B%{B){B-{B1{B5{B9{B={BA{BE{BI{BM{BQ{BU{BY{B]{Ba{Be{Bi{Bm{Bq{Bu{By{B}{>
+
+ž?¡G®@£×@P£×@Qì@šQì@ÈQì@èQìA(öA(öA$(öA4(öAD(öAT(öAd(öAt(öA{A{A{A{A¢{Aª{A²{Aº{AÂ{AÊ{AÒ{AÚ{Aâ{Aê{Aò{Aú{B
+=B
+=B	
+=B
+=B
+=B
+=B
+=B
+
+=B!
+=B%
+=B)
+=B-
+=B1
+=B5
+=B9
+=B=
+=BA
+=BE
+=BI
+=BM
+=BQ
+=BU
+=BY
+=B]
+=Ba
+=Be
+=Bi
+=Bm
+=Bq
+=Bu
+=By
+=B}
+=>  ?   @  @P  @  @š  @È  @è  A  A  A$  A4  AD  AT  Ad  At  A  A  A  A  A¢  Aª  A²  Aº  AÂ  AÊ  AÒ  AÚ  Aâ  Aê  Aò  Aú  B  B  B	  B
+  B  B  B  B
+  B!  B%  B)  B-  B1  B5  B9  B=  BA  BE  BI  BM  BQ  BU  BY  B]  Ba  Be  Bi  Bm  Bq  Bu  By  B}  >uÂ?žR@\)@O\)@®@§®@Ç®@ç®A×
+A×
+A#×
+A3×
+AC×
+AS×
+Ac×
+As×
+Aë
+Aë
+Aë
+Aë
+A¡ë
+A©ë
+A±ë
+A¹ë
+AÁë
+AÉë
+AÑë
+AÙë
+Aáë
+Aéë
+Añë
+Aùë
+B õÃBõÃBõÃB
+õÃBõÃBõÃBõÃB
+õÃB õÃB$õÃB(õÃB,õÃB0õÃB4õÃB8õÃB<õÃB@õÃBDõÃBHõÃBLõÃBPõÃBTõÃBXõÃB\õÃB`õÃBdõÃBhõÃBlõÃBpõÃBtõÃBxõÃB|õÃ>k
+?p€@žR@NžR@\)@§\)@Ç\)@ç\)A®A®A#®A3®AC®AS®Ac®As®A×
+A×
+A×
+A×
+A¡×
+A©×
+A±×
+A¹×
+AÁ×
+AÉ×
+AÑ×
+AÙ×
+Aá×
+Aé×
+Añ×
+Aù×
+B ë
+Bë
+Bë
+B
+ë
+Bë
+Bë
+Bë
+B
+ë
+B ë
+B$ë
+B(ë
+B,ë
+B0ë
+B4ë
+B8ë
+B<ë
+B@ë
+BDë
+BHë
+BLë
+BPë
+BTë
+BXë
+B\ë
+B`ë
+Bdë
+Bhë
+Blë
+Bpë
+Btë
+Bxë
+B|ë
+>aG®?(ö@{@N{@
+=@§
+=@Ç
+=@ç
+=A
+A
+A#
+A3
+AC
+AS
+Ac
+As
+AÂAÂAÂAÂA¡ÂA©ÂA±ÂA¹ÂAÁÂAÉÂAÑÂAÙÂAáÂAéÂAñÂAùÂB áHBáHBáHB
+áHBáHBáHBáHB
+áHB áHB$áHB(áHB,áHB0áHB4áHB8áHB<áHB@áHBDáHBHáHBLáHBPáHBTáHBXáHB\áHB`áHBdáHBháHBláHBpáHBtáHBxáHB|áH>W
+=?áH@
+p€@Mp€@žR@ŠžR@ÆžR@æžRA\)A\)A#\)A3\)AC\)AS\)Ac\)As\)A®A®A®A®A¡®A©®A±®A¹®AÁ®AÉ®AÑ®AÙ®Aá®Aé®Añ®Aù®B ×
+B×
+B×
+B
+×
+B×
+B×
+B×
+B
+×
+B ×
+B$×
+B(×
+B,×
+B0×
+B4×
+B8×
+B<×
+B@×
+BD×
+BH×
+BL×
+BP×
+BT×
+BX×
+B\×
+B`×
+Bd×
+Bh×
+Bl×
+Bp×
+Bt×
+Bx×
+B|×
+>LÌÍ?@
+ÌÍ@LÌÍ@ff@Šff@Æff@æffA33A33A#33A333AC33AS33Ac33As33AAAAA¡A©A±A¹AÁAÉAÑAÙAáAéAñAùB ÌÍBÌÍBÌÍB
+ÌÍBÌÍBÌÍBÌÍB
+ÌÍB ÌÍB$ÌÍB(ÌÍB,ÌÍB0ÌÍB4ÌÍB8ÌÍB<ÌÍB@ÌÍBDÌÍBHÌÍBLÌÍBPÌÍBTÌÍBXÌÍB\ÌÍB`ÌÍBdÌÍBhÌÍBlÌÍBpÌÍBtÌÍBxÌÍB|ÌÍ>B\?Qì@
+(ö@L(ö@{@Š{@Æ{@æ{A
+=A
+=A#
+=A3
+=AC
+=AS
+=Ac
+=As
+=A
+A
+A
+A
+A¡
+A©
+A±
+A¹
+AÁ
+AÉ
+AÑ
+AÙ
+Aá
+Aé
+Añ
+Aù
+B ÂBÂBÂB
+ÂBÂBÂBÂB
+ÂB ÂB$ÂB(ÂB,ÂB0ÂB4ÂB8ÂB<ÂB@ÂBDÂBHÂBLÂBPÂBTÂBXÂB\ÂB`ÂBdÂBhÂBlÂBpÂBtÂBxÂB|Â>8Qì?
+>@
+
+@K
+@
+Â@¥Â@ÅÂ@åÂAáHAáHA"áHA2áHABáHARáHAbáHAráHAp€Ap€Ap€Ap€A¡p€A©p€A±p€A¹p€AÁp€AÉp€AÑp€AÙp€Aáp€Aép€Añp€Aùp€B žRBžRBžRB
+žRBžRBžRBžRB
+žRB žRB$žRB(žRB,žRB0žRB4žRB8žRB<žRB@žRBDžRBHžRBLžRBPžRBTžRBXžRB\žRB`žRBdžRBhžRBlžRBpžRBtžRBxžRB|žR>.{?Â@
+áH@JáH@
+p€@¥p€@Åp€@åp€AžRAžRA"žRA2žRABžRARžRAbžRAržRA\)A\)A\)A\)A¡\)A©\)A±\)A¹\)AÁ\)AÉ\)AÑ\)AÙ\)Aá\)Aé\)Añ\)Aù\)B ®B®B®B
+®B®B®B®B
+®B ®B$®B(®B,®B0®B4®B8®B<®B@®BD®BH®BL®BP®BT®BX®B\®B`®Bd®Bh®Bl®Bp®Bt®Bx®B|®>#×
+?zá@
+=q@J=q@
+
+ž@¥
+ž@Å
+ž@å
+žA\A\A"\A2\AB\AR\Ab\Ar\AG®AG®AG®AG®A¡G®A©G®A±G®A¹G®AÁG®AÉG®AÑG®AÙG®AáG®AéG®AñG®AùG®B £×B£×B£×B
+£×B£×B£×B£×B
+£×B £×B$£×B(£×B,£×B0£×B4£×B8£×B<£×B@£×BD£×BH£×BL£×BP£×BT£×BX£×B\£×B`£×Bd£×Bh£×Bl£×Bp£×Bt£×Bx£×B|£×>?33@	@I@ÌÍ@€ÌÍ@ÄÌÍ@äÌÍAffAffA"ffA2ffABffARffAbffArffA33A33A33A33A¡33A©33A±33A¹33AÁ33AÉ33AÑ33AÙ33Aá33Aé33Añ33Aù33B BBB
+BBBB
+B B$B(B,B0B4B8B<B@BDBHBLBPBTBXB\B`BdBhBlBpBtBxB|>\)?ë
+@õÃ@HõÃ@zá@€zá@Äzá@äzáA=qA=qA"=qA2=qAB=qAR=qAb=qAr=qA
+žA
+žA
+žA
+žA¡
+žA©
+žA±
+žA¹
+žAÁ
+žAÉ
+žAÑ
+žAÙ
+žAá
+žAé
+žAñ
+žAù
+žB \B\B\B
+\B\B\B\B
+\B \B$\B(\B,\B0\B4\B8\B<\B@\BD\BH\BL\BP\BT\BX\B\\B`\Bd\Bh\Bl\Bp\Bt\Bx\B|\>
+ž?£×@Qì@HQì@(ö@€(ö@Ä(ö@ä(öA{A{A"{A2{AB{AR{Ab{Ar{A
+=A
+=A
+=A
+=A¡
+=A©
+=A±
+=A¹
+=AÁ
+=AÉ
+=AÑ
+=AÙ
+=Aá
+=Aé
+=Añ
+=Aù
+=B 
+B
+B
+B
+
+B
+B
+B
+B
+
+B 
+B$
+B(
+B,
+B0
+B4
+B8
+B<
+B@
+BD
+BH
+BL
+BP
+BT
+BX
+B\
+B`
+Bd
+Bh
+Bl
+Bp
+Bt
+Bx
+B|
+=õÂ?\)@®@G®@×
+@£×
+@Ã×
+@ã×
+Aë
+Aë
+A!ë
+A1ë
+AAë
+AQë
+Aaë
+Aqë
+AõÃAõÃAõÃAõÃA õÃAšõÃA°õÃAžõÃAÀõÃAÈõÃAÐõÃAØõÃAàõÃAèõÃAðõÃAøõÃB záBzáBzáB
+záBzáBzáBzáB
+záB záB$záB(záB,záB0záB4záB8záB<záB@záBDzáBHzáBLzáBPzáBTzáBXzáB\záB`záBdzáBhzáBlzáBpzáBtzáBxzáB|zá=áG®?{@
+=@G
+=@
+@£
+@Ã
+@ã
+AÂAÂA!ÂA1ÂAAÂAQÂAaÂAqÂAáHAáHAáHAáHA áHAšáHA°áHAžáHAÀáHAÈáHAÐáHAØáHAàáHAèáHAðáHAøáHB p€Bp€Bp€B
+p€Bp€Bp€Bp€B
+p€B p€B$p€B(p€B,p€B0p€B4p€B8p€B<p€B@p€BDp€BHp€BLp€BPp€BTp€BXp€B\p€B`p€Bdp€Bhp€Blp€Bpp€Btp€Bxp€B|p€=ÌÌÍ?ÌÍ@ff@Fff@33@£33@Ã33@ã33AAA!A1AAAQAaAqAÌÍAÌÍAÌÍAÌÍA ÌÍAšÌÍA°ÌÍAžÌÍAÀÌÍAÈÌÍAÐÌÍAØÌÍAàÌÍAèÌÍAðÌÍAøÌÍB ffBffBffB
+ffBffBffBffB
+ffB ffB$ffB(ffB,ffB0ffB4ffB8ffB<ffB@ffBDffBHffBLffBPffBTffBXffB\ffB`ffBdffBhffBlffBpffBtffBxffB|ff=žQì?
+@Â@EÂ@áH@¢áH@ÂáH@âáHAp€Ap€A!p€A1p€AAp€AQp€Aap€Aqp€AžRAžRAžRAžRA žRAšžRA°žRAžžRAÀžRAÈžRAÐžRAØžRAàžRAèžRAðžRAøžRB \)B\)B\)B
+\)B\)B\)B\)B
+\)B \)B$\)B(\)B,\)B0\)B4\)B8\)B<\)B@\)BD\)BH\)BL\)BP\)BT\)BX\)B\\)B`\)Bd\)Bh\)Bl\)Bp\)Bt\)Bx\)B|\)=£×
+?=q@
+ž@E
+ž@\@¢\@Â\@â\AG®AG®A!G®A1G®AAG®AQG®AaG®AqG®A£×A£×A£×A£×A £×Aš£×A°£×Až£×AÀ£×AÈ£×AÐ£×AØ£×Aà£×Aè£×Að£×Aø£×B QìBQìBQìB
+QìBQìBQìBQìB
+QìB QìB$QìB(QìB,QìB0QìB4QìB8QìB<QìB@QìBDQìBHQìBLQìBPQìBTQìBXQìB\QìB`QìBdQìBhQìBlQìBpQìBtQìBxQìB|Qì=\)?õÃ@zá@Dzá@=q@¢=q@Â=q@â=qA
+žA
+žA!
+žA1
+žAA
+žAQ
+žAa
+žAq
+žA\A\A\A\A \Aš\A°\Až\AÀ\AÈ\AÐ\AØ\Aà\Aè\Að\Aø\B G®BG®BG®B
+G®BG®BG®BG®B
+G®B G®B$G®B(G®B,G®B0G®B4G®B8G®B<G®B@G®BDG®BHG®BLG®BPG®BTG®BXG®B\G®B`G®BdG®BhG®BlG®BpG®BtG®BxG®B|G®=uÂ?®@×
+@C×
+@ë
+@¡ë
+@Áë
+@áë
+A õÃAõÃA õÃA0õÃA@õÃAPõÃA`õÃApõÃAzáAzáAzáAzáA záAšzáA°záAžzáAÀzáAÈzáAÐzáAØzáAàzáAèzáAðzáAøzáB =qB=qB=qB
+=qB=qB=qB=qB
+=qB =qB$=qB(=qB,=qB0=qB4=qB8=qB<=qB@=qBD=qBH=qBL=qBP=qBT=qBX=qB\=qB`=qBd=qBh=qBl=qBp=qBt=qBx=qB|=q=LÌÍ?ff@33@C33@@¡@Á@áA ÌÍAÌÍA ÌÍA0ÌÍA@ÌÍAPÌÍA`ÌÍApÌÍAffAffAffAffA ffAšffA°ffAžffAÀffAÈffAÐffAØffAàffAèffAðffAøffB 33B33B33B
+33B33B33B33B
+33B 33B$33B(33B,33B033B433B833B<33B@33BD33BH33BL33BP33BT33BX33B\33B`33Bd33Bh33Bl33Bp33Bt33Bx33B|33=#×
+?
+
+ž@\@B\@G®@¡G®@ÁG®@áG®A £×A£×A £×A0£×A@£×AP£×A`£×Ap£×AQìAQìAQìAQìA QìAšQìA°QìAžQìAÀQìAÈQìAÐQìAØQìAàQìAèQìAðQìAøQìB (öB(öB(öB
+(öB(öB(öB(öB
+(öB (öB$(öB((öB,(öB0(öB4(öB8(öB<(öB@(öBD(öBH(öBL(öBP(öBT(öBX(öB\(öB`(öBd(öBh(öBl(öBp(öBt(öBx(öB|(ö<õÂ?×
+@ë
+@Aë
+@õÃ@ õÃ@ÀõÃ@àõÃA záAzáA záA0záA@záAPzáA`záApzáA=qA=qA=qA=qA =qAš=qA°=qAž=qAÀ=qAÈ=qAÐ=qAØ=qAà=qAè=qAð=qAø=qB 
+žB
+žB
+žB
+
+žB
+žB
+žB
+žB
+
+žB 
+žB$
+žB(
+žB,
+žB0
+žB4
+žB8
+žB<
+žB@
+žBD
+žBH
+žBL
+žBP
+žBT
+žBX
+žB\
+žB`
+žBd
+žBh
+žBl
+žBp
+žBt
+žBx
+žB|
+ž<£×
+?\@G®@AG®@£×@ £×@À£×@à£×A QìAQìA QìA0QìA@QìAPQìA`QìApQìA(öA(öA(öA(öA (öAš(öA°(öAž(öAÀ(öAÈ(öAÐ(öAØ(öAà(öAè(öAð(öAø(öB {B{B{B
+{B{B{B{B
+{B {B${B({B,{B0{B4{B8{B<{B@{BD{BH{BL{BP{BT{BX{B\{B`{Bd{Bh{Bl{Bp{Bt{Bx{B|{<#×
+?G®@ £×@@£×@Qì@ Qì@ÀQì@àQìA (öA(öA (öA0(öA@(öAP(öA`(öAp(öA{A{A{A{A {Aš{A°{Až{AÀ{AÈ{AÐ{AØ{Aà{Aè{Að{Aø{B 
+=B
+=B
+=B
+
+=B
+=B
+=B
+=B
+
+=B 
+=B$
+=B(
+=B,
+=B0
+=B4
+=B8
+=B<
+=B@
+=BD
+=BH
+=BL
+=BP
+=BT
+=BX
+=B\
+=B`
+=Bd
+=Bh
+=Bl
+=Bp
+=Bt
+=Bx
+=B|
+=    ?  @   @@  @  @   @À  @à  A   A  A   A0  A@  AP  A`  Ap  A  A  A  A  A   Aš  A°  Až  AÀ  AÈ  AÐ  AØ  Aà  Aè  Að  Aø  B   B  B  B
+  B  B  B  B
+  B   B$  B(  B,  B0  B4  B8  B<  B@  BD  BH  BL  BP  BT  BX  B\  B`  Bd  Bh  Bl  Bp  Bt  Bx  B|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                  -32 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   91 / length of data axis 1                          NAXIS2  =                   91 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ?!1?)ì¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ?
+Æ?(þ?¯m®@ý¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ?óô?$h,?­E@:@29Q@_¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ?U"? É:?«ÎÌ@}@1Q@_«@]â@D¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ?¶P?
+*h?©ÿb@ŽÈ@0ià@^
+ø@
+ê@Ä@³ @ÊB¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ??w?š/ê@Í
+@/#@]7;@
+v)@P¶@³+B@ÊÎ@ààZ@÷Œ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ?
+x­?ì¥?Š`@ åX@.o@\O@
+O@ÜÜ@²·g@Éô@àl@÷G
+AÌAb|¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ?ÙÚ?M³?€?ÿû6@-²²@[gÊ@q@hý@²C@É
+@ßø¡@öÓ.AÖÜAD"A
+±hA)¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ?;	?®á?¢Á?þ+Î@,Êþ@Z@@õ#@±Ï¯@Èª;@ßÈ@ö_TAðA
+5A
+wzA(äÀA4RA?£¶¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ? 7?
+? ò6?ü\e@+ãJ@Ya@Šœ@I@±[Õ@È6a@ßí@õëyAcAÐHA
+=A(ªÓA4A?
+^AJò€AVDT¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >ùúÊ?q
+?"Ÿ?úì@*û@X°€@2Þ@
+j@°ç÷@ÇÂ@Þ@õwA)AYA
+A(päA3Þ*A?KoAJžŽAV%úAa@Aläð¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >òœ(?ÒL?SU?øœ@*Ù@WÈð@¿@@°t
+@ÇNš@Þ)5@õÁAï&A\lA
+É±A(6÷A3€<A?AJ~ÈAUì
+AaYRAlÆAx3ÞAÂÇ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >ë? 3Z?Ü?öî
+@),
+@Vá4@K&@%³@° >@ÆÚÊ@ÝµV@ôâAµ7A"}A
+ÂA'ýA3jMA>×AJDØAU²
+AadAl©AwùîA³Aj=A¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >äAà>ù)?Žs?õ
+¢@(Dh@Uù@×L@±Ø@¯d@Æfñ@ÝA|@ô
+A{IAèA
+UÕA'ÃA30`A>ŠAJ
+ëAUx1A`åvAlRŒAwÀA€AMHAëAºAcf¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >Ý<>ñë,?äú?óO)@'\¬@UÃ@cm@=ú@¯
+@Åó@ÜÍ@óš+AA[A® A
+åA'+A2öqA>c·AIÐüAU>BA`«AlÍAwAy­A0PAæóAAT:A
+ÜA£³µ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >ÕÆ>ê­??ñÀ@&t÷@T*@ï@Ê@®€«@Å8@ÜYÃ@ó4PAnAt³AáùA'O>A2ŒA>)ÉAIAUUA`qAkÞàAwL%A\¶AYAÉýA A7CAíçA£€A©[,A¯¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >Îõ>ão€?F?ï°G@%;@SBR@{µ@VA@®0Í@Å
+Y@Ûåå@òÀqAÍ~A:ÄAš
+A'OA2A=ïÚAI]ATÊeA`7«Ak€ñAw6A?ŸAöaA­AcšALAÐïA£A©>6A®ôÙAŽ«{AºTT¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >ÇKQ>Ü2?v¯?íàÞ@$¥@RZ@Û@âg@­Œó@Ä@Ûr
+@òLAA ÖAn
+A&ÛbA2HšA=µíAI#3ATxA_ýœAkkAvØIA"ÈAÙkAAF±AýUA³øA£jA©!?A®×âAŽAºE)A¿ûËAÅ€€¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >À
+®>Ôô
+?§6?ìe@#œÊ@Qrá@'ù@n@­I@Ä#¡@Úþ-@ñØ¹AY¢AÆèA4-A&¡rA2žA={þAHéDATVA_ÃÏAk1AvYAÐAŒsAsA)ºAà]A A£M€A©GA®ºëAŽqAº(1A¿ÞÕAÅxAËLAÐôó¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >žÐ
+>Í¶z?×Î?êAü@"Ö@P-@~@E@ú®@¬Õ;@Ã¯Ç@ÚS@ñdßAµAúAú@A&gA1ÔËA=BAH¯VAT
+A_âAj÷'AvdmAèÚA}AV!A
+ÃAÃfAz
+A£0­AšçPA®ôAŽTAº
+;A¿ÁÞAÅxAË/%AÐåÈAÖjAÜEC¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >±f>Æx?U?èr@!îY@O£p@}X@Ð@¬a\@Ã;è@Úu@ðñAåÆAS
+AÀQA&-A1ÜA="AHugASâ¬A_OòAjœ8Av*~AËâAA9)AïÌAŠpA]A£µAšÊYA®üAŽ7A¹îCA¿€æAÅ[AË-AÐÈÐAÖtAÜ6Aáì¹Aç¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >ªTÃ>¿:ó?8ì?æ£@!¥@N»»@|pÔ@ö@«í@ÂÈ@Ù¢@ð}&A«ÙAAdA%ó©A1`ïA<Î4AH;zASšÀA_AjJAuðA®ëAeA
+2AÒÖAyA@
+A¢öÀAš­bA®dAŽ©A¹ÑLA¿ïAÅ>AÊõ6AÐ«ÚAÖb}AÜ AáÏÄAçgAí=	Aòåâ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >£>·ý?is?äÓ¡@ 
+ç@MÓÿ@{@@«y€@ÂT0@Ù.Œ@ð	HAqéAß/ALuA%¹»A1' A<EAHASnÐA^ÜAjI\Au¶¡AôAHAÿ:AµÞAlA#%A¢ÙÈAškA®GA³ý±A¹ŽTA¿jøAÅ!AÊØ>AÐâAÖE
+AÛü)Aá²ÌAçioAí AòÖ¶AøXAþ61¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >Ù|>°¿??ã@@77@LìN@z¡g@+@@«Ì@ÁàX@Øºä@ïpA7þA¥CAA%ÎA0íA<ZZAGÇAS4äA^¢*AjpAu|µAtýA+ AâDAçAOA.A¢ŒÑAšsuA®*A³à»A¹_A¿NAÅ€AÊ»HAÐqëAÖ(AÛß2AáÕAçLyAí
+Aò¹¿AøpcAþ'BîÕBÃA¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >×>©è?
+Ê©?á4×@
+O@L@y¹²@·f@ªñ@Ál~@ØG
+@ï!AþAkVAØA%EáA0³&A< lAG²ARúøA^h=AiÕAuBÈAXAªAÅMA{ðA2Aé7A¢ÚAšV~A®
+!A³ÃÅA¹zhA¿1
+AÄç¯AÊQAÐTôAÖ
+AÛÂ;AáxÞAç/Aìæ%AòÉAøSlAþ
+BàYB»«BýB
+ki¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >^4>¢DD?û@?ßen@
+gÎ@K
+å@xÑþ@C@ª
+@Àø€@×Ó/@î­ŒAÄ#A1iA®A%
+ôA0y:A;æAGSÄARÁ
+A^.PAiAuÛA;A
+ñŽAšWA^úAAÌ@A¢äAš9A­ð*A³ŠÎA¹]qA¿AÄÊžAÊ[AÐ7ÿAÕî¡AÛ¥DAá[èAçAìÉ.AòÒAø6uAýíBÑÞB­0BB
+cÓB
+?%B¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  > > ?+×?Ý@
+@J51@wêJ@Ï±@©ª=@ÀÉ@×_U@î9âA6A
+÷|AdÁA$ÒA0?LA;¬AGØAR
+A]ôbAiašAtÎîA
+A
+ÔœAaABAø§A¯JA¢eíAš
+A­Ó4A³×A¹@zAŸ÷
+AÄ­ÁAÊdeAÐAÕÑ«AÛOAá>ñAæõAì¬8AòbÛAø~AýÐ"BÃcBŽBzB
+UXB
+0©B
+ûBçMB»¹¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >}ÅØ>Èü?\n?ÛÆ@e@IM}@w@[×@©6c@Àï@Öë{@íÆAPIA
+œA*ÕA$A0_A;r¥AFßêARM0A]ºvAi'»At A#A
+·ÆAnjA%
+AÛ±ATA¢H÷A§ÿA­¶=A³làA¹#AŸÚ'AÄÊAÊGnAÏþAÕŽµAÛkXAá!ûAæØAìAAòEäA÷üAý³+BŽçB9BkB
+FÜB
+".BýBØÑBŽ#BuBcá¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >oJ>X?}
+?Ù÷3@°±@HeÈ@vá@çý@šÂ@¿@Öw¡@íR-A\A
+¡AðçA$^-A/ËsA;8žAF¥ýARCA]AhíÎAt[AÈYA
+ÐAQsAAŸºAu]A¢,A§â€A­GA³OêA¹AŸœ0AÄsÔAÊ*wAÏáAÕŸAÛNaAáAæ»šAìrKAò(ïA÷ßAý4BŠlBŸB]B
+8aB
+³BïBÊVB¥šBùB\KB
+7B!
+	¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >`ÏI>
+Mµ?y{8?Ø'Ë@Èý@G~@u3,@t"@šN®@¿);@ÖÆ@ìÞSAÜoA
+IµA¶úA$$?A/
+A:þËAFlAQÙVA]FAh³áAt!&AlA
+}ÙA4|Aë A¡ÃAXfA¢
+A§Å­A­|QA³2ôAžéAŸ :AÄVÝAÊ
+AÏÄ$AÕzÇAÛ1jAàèAæ±AìUUAò
+øA÷ÂAýy?BñBsBBNB
+)æB
+7BàB»ÛB,Br~BMÐB
+)!B!sB#ßÅB&Ž1¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >RT >|  ?uÜf?ÖXb@áH@F_@tKw@ H@§ÚÔ@Ÿµ`@Õì@ìjyA¢A
+ÇA}
+A#êSA/WA:ÄÝAF2#AQiA]
+¯AhyôAsç9ATA
+`ãAAÎ)AÌA;pA¡òA§š¶A­_ZA³ýAžÌ¡AŸDAÄ9çAÉðAÏ§-AÕ]ÐAÛtAàËAæºAì8^AñïA÷¥¥Aý\HBuBdÇB@B
+jB
+öŒBÒB­_B±BdB?TB
+ŠB õøB#ÑIB&¬B)íB,\Y¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >CØž>m€Ø?r=?Ôù@ù@E®«@scÃ@m@§fú@ŸA@Õ
+@ëöAhA
+ÕÚAC A#°eA/
+«A:ñAEø6AQe{A\ÒÁAh@As­MAA
+CìAúA±3AgÖA
+yA¡Õ
+A§ÀA­BcA²ùAž¯ªAŸfMAÄ
+ñAÉÓAÏ7AÕ@ÚAÚ÷}Aà® AædÄAìgAñÒ
+A÷®Aý?QBzúBVLB1B
+
+ïB
+èABÃBäBz6BUB0ÙB
+
++B ç|B#ÂÎB& B)yqB,TÃB/0B2¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >5]q>_)?nÃ?Ò¹@ß@DÆö@r|@@Šó@œÍ«@Ôš8@ëÄA.šA
+íA	3A#vxA.ãŸA:QAEŸIAQ+A\ÔAhAss_A~à¥A
+&öAÝA<AJàAA¡ž&A§nÉA­%lA²ÜAž³AŸIVAÃÿúAÉ¶AÏmAAÕ#äAÚÚAà*AæGÍAëþpAñµA÷k·Aý"ZBlBGÐB#"B	þtB
+ÙÅBµBiBkºBG
+B"^B
+ý¯B ÙB#ŽSB&€B)jöB,FHB/!B1üëB4Ø=B7¬©¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >&â)>P®?k ?Ðê/@*/@CßF@q^@€»@ŠG@œYÓ@Ô4_@ëëA ô»A
+bAÏGA#<A.©ÒA:AE]APñ¢A\^èAgÌ.As9sA~Š¹A
+
+ AÀ£AwGA-êAäA¡1A§QÔA­wA²¿AžuœAŸ,aAÃãAÉ§AÏPKAÕîAÚœAàt5Aæ*ØAëá{Añ
+A÷NÁAýeB^B9UB§B	ïøB
+ËJBŠBíB]?B8BâB
+ï4B ÊB#¥×B&)B)\{B,7ÌB/
+B1îpB4ÉÁB7¥B:eB=TÑ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >fâ>B3?ga
+?ÏŸ@Bv@B÷@p¬Š@0ß@Š
+k@Œå÷@ÓÀ@êA ºÍA
+(AXA#A.oäA9Ý)AEJoAP·ŽA\$úAg?Arÿ
+A~lÊAíA£¬AZOAòAÇA¡~9A§4ÜA¬ëA²¢#AžXÆAŸiAÃÆ
+AÉ|°AÏ3SAÔéöAÚ AàW=Aæ
+áAëÄAñ{'A÷1ÊAüèmBOB*ÚB,B	á}B
+ŒÏB BsrBNÄB*BgB
+à¹B Œ
+B#\B&r®B)MÿB,)QB/£B1ßôB4»FB7B:qéB=M;B@(BBüù¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  >	ë>3·?cÂD?ÍKQ@ZÀ@B×@oÄï@œ@¥@Œr
+@ÓLš@ê'4A àA
+î%A[kA"È±A.5öA9£<AEAP}ÇA[ë
+AgXRArÅA~2ÝAÐAµA=XAóüAªA¡aBA§æA¬ÎA²
+,Až;ÐAœòsAÃ©AÉ_¹AÏ\AÔÍ AÚ£Aà:FAåðêAë§Añ^1A÷ÔAüËwBA
+B
+_B÷°B	ÓB
+®TB¥Bd÷B@HBBöìB
+Ò=B ­B#áB&d2B)?B,ÖB.ö'B1ÑyB4¬ËB7
+B:cnB=>ÀB@BBõcBEÐµBH¥!¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  =öà©>%<3?`#k?Ë{ä@s	@A(!@nÝ9@I)@¥#Ž@»þ@@ÒØÍ@é³YA FòA
+Ž8A!}A"ÂA-üA9iNADÖAPCÙA[±Ag
+dArªA}øñA³
+AiŸA bA×AšA¡DLAŠúïA¬±A²h6Až
+ÙAœÕ|AÃ AÉBÃAÎùfAÔ°	AÚf¬Aà
+PAåÓóAëAñA:Aö÷ÝAü®B2B
+ãBé5B	ÄB
+ØB{*BV|B1ÍB
+BèpB
+ÃÂB B#zeB&U·B)1	B,
+ZB.ç¬B1ÂþB4OB7y¡B:TóB=0DB@
+BBæèBEÂ9BHBKxÝBNMI¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  =Ùê>Àí?\?É¬{@U@@@l@mõ@ÕN@€¯Ú@»g@Òdò@é?~A 
+A
+zJAçA"TÖA-ÂA9/`ADŠAP	ìA[w1AfäwArQœA}¿A%ALÈAlAºAp²A¡'UAŠÝøA¬A²K?AžâAœžAÃo)AÉ%ÌAÎÜpAÔAÚI¶Aà YAå¶üAëm Añ$CAöÚæAüB$BÿhBÚºB	¶
+B
+]Bl¯BH B#RBþ€BÙõB
+µGB B#kêB&G<B)"B+ýßB.Ù1B1ŽB4ÔB7k&B:FwB=!ÉB?ýBBØlBE³ŸBHBKjaBNE³BQ!BSõq¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  =Œó>E?XåÀ?ÇÝ@£@?X¶@m
+Î@as@€;ÿ@»@Ññ@èË€@ÿŠ0A
+@]A­¢A"èA-.A8õtADb¹AOÏþA[=DAfªArÏA}
+Ay.A/ÒAæuAASŒA¡
+^AŠÁA¬w¥A².HA·äìAœAÃR2AÉÖAÎ¿yAÔv
+AÚ,ÀAßãcAåAëP©AñLAöœðAütBBðíBÌ>B	§B
+âB^3B9
+B×Bð(BËzB
+ŠÌB 
+B#]oB&8ÀB)B+ïdB.ÊµB1ŠB4YB7\ªB:7üB=NB?îBBÉñBE¥CBHBK[æBN78BQBSíÛBVÉ-BY¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  =ý=ó@?UFæ?Æ
+¡@»ç@>pÿ@l&@í@£È$@º¢°@Ñ}<@èWÈ@ÿ2SA
+oAsµA!àúA-N?A8»
+AD(ËAOA[VAfpAqÝáA}K'A\7AÚAÉ}A!A6ÄA ígAŠ€
+A¬Z­A²QA·ÇôAœ~AÃ5;AÈëÞAÎ¢AÔY%AÚÈAßÆkAå}Aë3²AðêUAö øAüWBBâpBœÂB	B
+teBO·B+	BZBá¬BŒþB
+OB s¡B#NóB&*DB)B+àçB.Œ9B1B4rÜB7N.B:)B=ÑB?à#BB»uBEÆBHrBKMjBN(»BQ
+BSß_BVº°BYB\qTB_EÀ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  =t=Ö?Qš?Ä>6@Ô2@=I@k>a@yœ@£TH@º.Õ@Ñ	a@çãí@þŸyA
+ÌA9ÈA!§
+A-SA8ACîÝAO\#AZÉiAf6¯Aq£ôA}9A?@AõãA¬Ac*AÍA ÐqAŠA¬=·A±ô[A·ªýAœa¡AÃDAÈÎçAÎ
+AÔ<.AÙòÑAß©uAå`Aë»AðÍ_AöAü:¥B ø£BÓõB¯GB	B
+eêBA<B
+B÷ßBÓ1B®B
+ÔB e&B#@wB&ÉB(÷B+ÒlB.­ŸB1B4daB7?³B:B<öVB?ÑšBB¬ùBEKBHcBK>îBN@BPõBSÐãBV¬5BYB\bØB_>*Bb|Bdíè¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  =LÍ=¹Šä?N	:?ÂnÌ@ì}@<¡@jV¬@â@¢ào@¹ºû@Ð@çp@þJA
+AÿÚA!m A,ÚfA8G«ACŽñAO"6AZ{AeüÁAqjA|×LA"IAØíAAF3Aü×A ³zAŠj
+A¬ ÁA±×dA·AœD«AÂûMAÈ±ñAÎhAÔ7AÙÕÛAß~AåC!AêùÅAð°hAög
+Aü
+¯B ê(BÅzB ÌB	|
+B
+WoB2ÀBBédBÄµB B
+{YB VªB#1üB&
+NB(èB+ÃñB.CB1zB4UæB717B:
+B<çÛB?Ã,BB~BEyÐBHU!BK0sBN
+ÅBPçBSÂhBVºBYy
+B\T]B_/¯Bb
+ BdæRBgÁ€Bj¿  ¿  ¿  ¿  ¿  ¿  =2³=°8?Jjd?À`@Ç@;¹ß@inö@@¢l@¹G@Ð!¬@æü8@ýÖÂA
+X§AÅíA!32A, wA8
+œAC{ANèHAZUAeÂÓAq0A|`ASA»öArA)=AßàA AŠM'A¬ÊA±ºmA·qAœ'ŽAÂÞWAÈûAÎKAÔAAÙžäAßoAå&+AêÜÎAðqAöJAü žB Û­B¶ÿBPB	m¢B
+HôB$EBÿBÚèB¶:BB
+lÝB H/B##B%þÒB(Ú$B+µvB.ÇB1lB4GkB7"ŒB9þB<Ù_B?Ž±BBBEkTBHFŠBK!øBMýIBPØBS³íBV>BYjB\EâB_!3Baü
+Bd××Bg³(BjzBmiÌBp>8¿  ¿  ¿  ¿  <°/=s4?FË?ŸÏø@
+
+@:Ò*@hB@
+-@¡ø¹@žÓE@Ï­Ñ@æ]@ýbèA
+
+¹AÿA ùEA,fA7ÓÐACAAN®[AZ¡AeæApö,A|csAè]A AU£A
+FAÂéA yAŠ00A«æÓA±wA·TAœ
+œAÂÁaAÈxAÎ.§AÓåKAÙíAßRAå	4Aê¿×Aðv{Aö-
+AûãÁB Í2BšBÕB	_'B
+:xBÊBñ
+BÌmB§¿BB
+^bB 9ŽB#B%ðWB(Ë©B+ŠúB.LB1]B48ïB7AB9ïB<ÊäB?Š6BBBE\ÙBH8+BK|BMîÎBPÊ BS¥qBVÃBY\B\7fB_žBaî
+BdÉ[Bg€­BjÿBm[PBp6¢BsôBuæ`¿  ¿  ;òÃë=E
+ê?C,œ?œ @
+5^@9êu@g@ªS@¡ß@ž_k@Ï9÷@æ@üïA	äÍARA ¿WA,,A7ãAC)ANtnAYá³AeNùApŒ?A|)
+AËfA	A8­AïPA¥óA \AŠ9A«ÉÝA±A·7#AŒíÇAÂ€jAÈ[
+AÎ±AÓÈTAÙ~÷Aß5Aäì=Aê¢áAðYAö'AûÆËB Ÿ·BBuZB	P«B
++ýBOBâ BœòBDBtB
+OçB +8B#B%áÜB(œ-B+B.sÑB1O"B4*tB7ÆB9áB<ŒiB?»BBs
+BEN^BH)¯BKBMàSBP»€BSöBVrHBYMB\(ëB_=BaßBdºàBg2BjqBmLÕBp('BsxBuÞÊBxº
+B{    =
+??è?»1"@
+Mš@9¿@f·×@6x@¡@·ë@ÎÆ
+@å š@ü{4A	ªàA%A 
+kA+ò°A7_õABÍ;AN:AY§ÇAe
+ApQA{ïA®oAeA¶AÒYAýA ? A¥öCA«¬æA±cA·-AŒÐÐAÂsAÈ>AÍôºAÓ«]AÙbAß€AäÏGAê
+ëAð<Aõó1Aû©ÔB °;BBfßB	B0B
+
+BøÓBÔ%B¯wBÈBfB
+AlB 
+œB"øB%Ó`B(®²B+B.eUB1@§B4ùB6÷JB9ÒB<­îB??BBdBE?ãBH4BJöBMÑ×BP­)BS{BVcÌBY?
+B\pB^õÁBaÑBd¬eBg¶BjcBm>ZBp«BrôýBuÐOBx« B{òB~bD¿  ?=š\?¹a·@
+eó@8
+@eÐ"@Â@ *@·w¶@ÎRB@å,Î@üZA	pòAÞ8A K~A+žÃA7&	ABNAN AYmÙAdÛApHeA{µ«AyAH
+Aþ¿AµcAlA "©A¥ÙMA«ðA±FA¶ý6AŒ³ÙAÂj}AÈ! AÍ×ÃAÓgAÙE
+AÞû­Aä²QAêhôAðAõÖ;AûÝB ¡ÀB}BXcB	3µB
+BêXBÅªB ûB|MBWB
+2ðB BB"éB%ÄåB( 7B+{B.VÚB12,B4
+}B6èÏB9Ä!B<rB?zÄBBVBE1gBH
+¹BJè
+BMÃ\BP®BSyÿBVUQBY0£B\
+ôB^çFBaÂBdéBgy;BjTBm/ÞBp
+0BræBuÁÓBx%B{xwB~SÈB~}¿  ¿  @	ì@73U@dèl@NÂ@ )N@·Û@ÍÞg@äžó@û~A	7A€JA A+~ÕA6ìABY`AMÆŠAY3ëAd¡0ApvA{{ŒAtA+$AáÈAkAOA ²A¥ŒUA«røA±)A¶à?AŒâAÂM
+AÈ(AÍºÌAÓqoAÙ(AÞÞ¶AäYAêKüAð Aõ¹CAûoæB EBnBIèB	%:B
+ BÛÝB·/BBmÒBI#B
+$uBÿÇB"ÛB%¶jB(ŒB+m
+B.H_B1#°B3ÿB6ÚTB9µ¥B<÷B?lIBBGBE"ìBGþ>BJÙBMŽáBP3BSkBVFÖBY"'B[ýyB^ØËBaŽ
+BdnBgjÀBjFBm!cBoüµBrØBu³XBxªB{iûB~EMB~o¿  ¿  ¿  ¿  @do
+@Úè@µt@¶ @Íj@äE@û£AýAj]A×£A+DèA6²-ABsAM¹AXùþAdgDAoÔA{AÏAWA.AÄÑA{tA2Aè»A¥^A«VA±
+¥A¶ÃHAŒyìAÂ0AÇç2AÍÕAÓTxAÙ
+
+AÞÁ¿AäxbAê/Aïå©AõLAûRðB ÉB`B;mB	ŸB
+òBÍbBš³BB_WB:šB
+úBñKB"ÌB%§ïB(@B+^B.9äB15B3ðB6ËØB9§*B<|B?]ÍBB9BEqBGïÂBJËBMŠfBP·BS]	BV8[BY¬B[îþB^ÊOBa¥¡BdóBg\DBj7BmèBoî9BrÉBu€ÝBx.B{[B~6ÒB~`¿  ¿  ¿  ¿  ¿  ¿  @xÂ@¶
+%@Ìö±@ãÑ=@ú«ÊAÃ*A0pAµA+
+ûA6xAAAåAMRËAXÀAd-WAoA{âA:Añ8A§ÛA^~A!AËÄA¥hA«9
+A°ï®A¶ŠRAŒ\õAÂAÇÊ<AÍßAÓ7AØî%AÞ€ÈAä[lAêAïÈ²AõVAû5ùB vNBQ B,ñB	CB
+ãBŸæB8BuBPÛB,-B
+BâÐB"Ÿ"B%sB(tÅB+PB.+hB1ºB3â
+B6œ]B9¯B<t B?ORBB*€BEõBGáGBJŒBMêBPs<BSNBV)ßBY1B[àB^»ÔBa&BdrwBgMÉBj)BmlBoßŸBr»BuaBxq³B{MB~(VB~R¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  @Ìº @ã]c@ú7ïA=AöAcÈA*ÑA6>SAA«AMßAX$AcóiAo`¯AzÍõA
+AÔAAäAAAø+A®ÎA¥eqA«
+A°ÒžA¶[AŒ?þAÁö¢AÇ­EAÍcèAÓAØÑ/AÞÒAä>uAéõAï«ŒAõb_AûB gÓBC$B
+vBùÈB
+ÕB°kBœBgBB`B
+²B
+ùBÔUB"¯§B%øB(fJB+AB.
+íB0ø?B3ÓB6®âB94B<e
+B?@×BB
+(BD÷zBGÒÌBJ®
+BMoBPdÁBS@BVdBXö¶B[ÒB^­YBa«BdcüBg?NBjBlõñBoÑCBr¬BuæBxc8B{>B~ÛB~C¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  @ùû<AOOAŒA)ÚA* A6eAAq«ALÞðAXL6Ac¹|Ao&ÁAzA §A·JAmîA$AÛ4AØA¥H{Aªÿ
+A°µÁA¶ldAŒ#AÁÙ«AÇNAÍFòAÒýAØŽ8AÞjÜAä!AéØ"AïÅAõEhAúü
+B YXB4ªBûBëLB
+ÆB¡ðB}ABXB3åB6B
+êBÅÚB"¡+B%|}B(WÏB+3 B.rB0éÃB3ÅB6 gB9{žB<W
+B?2\BB
+­BDèÿBGÄPBJ¢BMzôBPVEBS1BV
+éBXè:B[ÃB^ÞBaz/BdUBg0ÓBj
+$BlçvBoÂÇBrBuykBxTŒB{0B~
+`B~5 ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A<A
+ïíA*]3A5ÊxAA7ŸAL¥AXIAcAnìÔAzZAã°ATAP÷AAŸ>AtáA¥+Aªâ(A°ËA¶OnAŒAÁŒŽAÇsXAÍ)ûAÒàAØBAÞMåAäAé»,AïqÏAõ(rAúßB JÜB&.BBÜÒB
+ž#BtBnÆBJB%iB »B
+Ü
+B·^B"°B%nB(ISB+$¥B-ÿ÷B0ÛHB3¶B6ëB9m=B<HB?#àBAÿ2BDÚBGµÕBJ'BMlxBPGÊBS#
+BUþmBXÙ¿B[µB^bBakŽBdGBg"WBiý©BlØûBoŽLBrBujïBxFAB{!B}üäB~&¥¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A*>ÚA5A@ýÑALkAWØ\AcE¡An²çAz .AÆ¹A}]A4 Aê€A¡GAWêA¥AªÅ1A°{ÔA¶2xA»éAÁŸAÇVaAÍ
+AÒÃšAØzKAÞ0îAãçAé5AïTØAõ
+|AúÂB <aB³BóBÎVB
+©šBúB`KB;BîBò@B
+ÍBšãB"5B%_B(:ØB+*B-ñ{B0ÌÍB3šB6pB9^ÂB<:B?eBAð·BDÌBG§ZBJ«BM]ýBP9OBS BUïòBXËDB[ŠB^çBa]9Bd8BgÜBiï.BlÊBo¥ÑBr#Bu\tBx7ÆB{B}îiB~*¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A@ßwAL1(AWnAc
+³AnxùAyæ>A©ÃA`fAAÍ¬AOA:óA€ñAªš9A°^ÝA¶A»Ì#AÁÇAÇ9jAÌð
+AÒŠ°AØ]SAÞ÷AãÊAé=Aï7áAôîAú¥'B -äB	6BäB¿ÚB
+,Bv}BQÏB-!BrBãÃB
+¿BgB"užB%Q
+B(,\B+­B-âÿB0ŸQB3¢B6tôB9PFB<+B?éBAâ:BDœBGÞBJt/BMOBP*ÒBS$BUávBXŒÇB[B^skBaNŒBd*Bg`Bià±BlŒBoUBrrŠBuMøBx)JB{B}ßíB~	®¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AWAbÑÆAn?
+Ay¬QAÌACoAúA°¶AgXA
+üA€ÔAªCA°AæAµøA»¯-AÁeÐAÇ
+sAÌÓAÒºAØ@]AÝ÷ Aã­£AédGAïêAôÑAú0B iBú»BÖ
+B±^B
+°BhBCTB
+¥Bù÷BÕIB
+°BëB"g=B%BB(
+àB*ù2B-ÔB0¯ÕB3'B6fyB9AÊB<
+
+B>ønBAÓ¿BD¯BGbBJeŽBMABP
+WBR÷©BUÒúBX®LB[B^dïBa@ABdBföäBiÒ6Bl­BoÙBrd+Bu?}BxÎBzö B}ÑrB}û3¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  An ²AyrdAoÕA&yAÝ
+A¿AJcAA€·šAªnLA°$ïAµÛA»6AÁHÙAÆÿ}AÌ¶ AÒlÃAØ#gAÝÚ
+Aã­AéGPAîýóAôŽAúk:B îBì?BÇB¢ãB
+~4BYB4ØB*Bë|BÆÍB
+¢B}qB"XÂB%4B(eB*ê·B-ÆB0¡ZB3|¬B6WýB93OB<¡B>éòBAÅDBD BG{çBJW9BM2BP
+ÜBRé.BUÄBXÑB[{"B^VtBa1ÆBd
+BfèiBiÃ»Bl
+Boz^BrU°Bu1Bx
+SBzç¥B}ÂöB}ìž¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A`©A	AÀ%AvÉA-lAäA€³AªQVA°øAµŸA»u?AÁ+ãAÆâAÌ)AÒOÍAØpAÝœAãs·Aé*ZAîàýAô AúNCB sBÝÅB¹BgB
+o¹BK
+B&\B®BÝ BžRB
+€BnõB"JGB%%B( êB*Ü;B-·B0ßB3n0B6IB9$ÔB< %B>ÛwBA¶ÉBDBGmlBJHŸBM$BOÿaBRÚ²BU¶BXVB[l§B^GùBa#JBcþBfÙîBiµ?BlBokãBrG4Bu"BwýØBzÙ)B}Ž{B}Þ=¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A°ùAYÒAuAÇA€}ŒAª4_A¯ëAµ¡ŠA»XHAÁìAÆÅAÌ|3AÒ2ÖA×éyAÝ 
+AãVÀAé
+cAîÄAôzªAú1MAÿçïBÏIBªB
+íB
+a>B<BáBó3BÎB©ÖB
+
+(B`zB";ÌB%
+B'òoB*ÍÁB-©B0cB3_µB6;B9XB;ñªB>ÌüBAšMBDBG^ñBJ:BBMBOðæBRÌ7BU§BXÚB[^,B^9~BaÏBcð!BfËrBiŠÄBlBo]gBr8¹Bu
+Bwï\BzÊ®B}Š B}ÏÁ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AIAª"A€`ÅAªiA¯Î
+Aµ¯A»;SAÀñöAÆšAÌ_<AÒßA×ÌAÝ&Aã9ÉAèðmAî§Aô]³AúWAÿÊøBÀÎB BwqB
+RÃB.B	fBä·BÀ	B[B
+v¬BQþB"-PB%¢B'ãôB*¿EB-B0uéB3Q:B6,B9ÝB;ã/B>ŸBAÒBDu$BGPuBJ+ÇBMBOâjBRœŒBUBXt_B[O±B^+BaTBcáŠBfŒ÷BiIBlsBoNìBr*>BuBwàáBzŒ3B}B}ÁF¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A€QA©úrA¯±Aµg¹A»
+\AÀÔÿAÆ£AÌBFAÑøèA×¯AÝf/Aã
+ÓAèÓvAîAô@œAù÷`Aÿ®B²SB€BhöB
+DHBBúëBÖ=B±BßB
+h1BCB"
+ÔB$ú&B'ÕxB*°ÊB-
+B0gmB3B¿B6
+B8ùbB;Ô³B>°BAWBDfšBGAúBJ
+LBLøBOÓïBR¯ABUBXeäB[A6B^
+B`÷ÙBcÓ*Bf®|BiÎBleBo@qBrÂBt÷BwÒfBz­·B}	B}²Ë¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A¯¡éAµJÂA»eAÀž	AÆn¬AÌ%OAÑÛóA×AÝI8AâÿÜAè¶Aîm#Aô#ÆAùÚiAÿ
+B£×B)BZ{B
+5ÌB
+BìpBÇÁB£B~eB
+Y¶B5B"YB$ë«B'ÆüB*¢NB-} B0XòB34DB6B8êçB;Æ9B>¡BA|ÛBDX-BG3BJÐBLê"BOÅtBR ÅBU|BXWiB[2ºB^
+B`é^BcÄ¯Bf Bi{RBlV€Bo1öBr
+GBtèBwÃêBz<B}zB}€O¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  Aºò9AÀAÆQµAÌYAÑŸüA×uAÝ,CAââæAèAîP,AôÏAùœsAÿtB\Bp®BKÿB
+'QB£BÝôB¹FBBoéB
+K;B&B"ÞB$Ý/B'žB*ÓB-o$B0JvB3%ÈB6B8ÜlB;·œB>BAnaBDI²BG%BJ UBLÛ§BO¶øBRJBUmBXHíB[$?B]ÿB`ÚâBc¶4BfBil×BlH)Bo#zBqþÌBtÚ
+BwµoBzÁB}lB}Ô¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AÆBAËëbAÑ¢A×X©AÝLAâÅïAè|Aî36AóéØAù |AÿWBáBb3B=B
+ÖB
+ô'BÏyBªËB
+BanB
+<ÀBB!ócB$ÎµB'ªB*
+WB-`©B0;ûB3LB5òB8ÍðB;©BB>BA_åBD;7BGBIñÚBLÍ+BOš}BRÏBU_ BX:rB[ÄB]ñB`ÌgBc§¹Bf
+Bi^\Bl9®BoÿBqðQBtË¢BwŠôBzFB}]B}Y¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AÑÙA×;²AÜòUAâšùAè_Aî?AóÌãAùAÿ:'BxfBS·B/	B
+
+[B
+å¬BÀþBOBw¡BRóB
+.DB	B!äèB$À9B'B*vÝB-R.B0-B3ÑB5ä#B8¿tB;ÆB>vBAQjBD,ŒBG
+BIã_BLŸ±BOBRuSBUP¥BX+÷B[HB]âB`œìBc=BftBiOáBl+2BoBqáÖBtœ'BwyBzsÊB}O
+B}xÞ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AÜã)AâAèB¥AíùIAó¯ìAùfAÿ
+1BiêBE<B B
+ûßB
+×1B²BÔBi&BDwB
+ÉB
+ûB!ÖlB$±ŸB'B*haB-C³B0B2úVB5Õ§B8°ùB;KB>gBABîBD
+@BFùBIÔäBL°5BOBRfÙBUB*BX
+{BZøÍB]ÔB`¯pBcÂBffBiAeBl
+·Bnø	BqÓZBt®¬BwþBzeOB}@¡B}jb¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  Aè3yAíÜRAóõAùIAÿ ;B[oB6ÁBB
+ídB
+È¶B€BYBZ«B5üB
+NB
+ìB!ÇñB$£CB'~B*YæB-58B0B2ëÛB5Ç-B8¢~B;}ÏB>Y!BA4sBDÄBFëBIÆhBL¡ºBO}
+BRX]BU3¯BXBZêRB]Å£B` õBc|GBfWBi2êBl<BnéBqÄßBt 1Bw{BzVÔB}2&B}[ç¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AóÉAù,¢AþãDBLôB(EBB
+ÞéB
+º:BBpÞBL/B'B
+ÓB
+Þ$B!¹vB$ÇB'pB*KkB-&ŒB0B2Ý`B5ž±B8B;oUB>JŠBA%÷BDIBFÜBI·ìBL>BOnBRIâBU%4BX 
+BZÛ×B]·)B`zBcmËBfI
+Bi$oBkÿÀBnÛBq¶dBtµBwmBzHYB}#ªB}Ml¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AþÔB>xBÊBõ
+B
+ÐmB
+«¿BBbbB=ŽBBôWB
+Ï©B!ªûB$LB'aB*<ïB-AB/óB2ÎäB5ª6B8
+B;`ÙB><+BA}BCòÎBFÎBI©qBLÃBO`BR;fBUžBWò
+BZÍ\B]š­B`ÿBc_QBf:¢BióBkñEBnÌBq§èBt:Bw^Bz9ÝB}/B}>ñ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B4Bæ B
+ÁòB
+DBxBSçB/9B
+BåÜB
+Á.B!B$wÑB'S#B*.tB-	ÆB/åB2ÀiB5»B8w
+B;R^B>-°BA	BCäSBF¿¥BIöBLvGBOQBR,ëBU<BWãBZŸàB]2B`uBcPÕBf,'BiyBkâÊBnŸBqmBtt¿BwPBz+bB}ŽB}0u¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B
+º\B
+ÈBjBElB œBüB×aB
+²²B!B$iVB'D§B*ùB,ûKB/ÖB2±îB5?B8hB;CãB>4B@úBCÕØBF±)BI{BLgÍBOC
+BR
+oBTùÁBWÕBZ°dB]¶B`gBcBZBf
+¬BhøýBkÔOBn¯¡BqòBtfCBwABz
+çB|ø8B}!ú¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BbB6ïBABíBÈäB
+€6B!B$ZÙB'6+B*}B,ìÎB/È B2£rB5~ÃB8ZB;5fB>žB@ì
+BCÇ[BF¢­BI}ÿBLYPBO4¢BRôBTëEBWÆBZ¡èB]}:B`XBc3ÝBf/BhêBkÅÓBn¡$Bq|vBtWÈBw3BzjB|éŒB}¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B
+«BßBºiB
+»B!q
+B$L^B''°B*B,ÞSB/¹¥B2öB5pHB8KB;&ëB>=B@ÝBCžàBF2BIoBLJÕBO&'BRxBTÜÊBWž
+BZmB]nŸB`JBc%bBf ³BhÜBk·WBn©BqmûBtILBw$ByÿðB|ÛAB}¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B²ÓB
+?B!bB$=ãB'4B)ôB,ÏØB/«)B2{B5aÍB8=
+B;pB=óÂB@ÏBCªeBF
+¶BIaBL<ZBO«BQòýBTÎOBW© BZòB]`DB`;BcæBeò8BhÍBkšÛBn-Bq_Bt:ÑBw#ByñtB|ÌÆB|ö¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B!ZûB$/gB'
+¹B)æ
+B,Á\B/®B2x B5SQB8.£B;	õB=åFB@ÀBCêBFw;BIRBL-ÞBO	0BQäBT¿ÓBW%BZvwB]QÈB`-BclBeãœBh¿Bk`Bnu²BqQBt,UBw§ByâùB|ŸKB|è
+¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B'#B)×B,²áB/3B2iB5DÖB8 (B:ûyB=ÖËB@²
+BCnBFhÀBIDBLcBNúµBQÖBT±XBWªBZgûB]CMB`
+BbùðBeÕBBh°BkåBng6BqBBt
+ÚBvù+ByÔ}B|¯ÏB|Ù¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B,«JB/¶B2[B56ZB8«B:ìýB=ÈOB@£ BC~òBFZDBI5BLçBNì9BQÇBT¢ÜBW~-BZYB]4ÑB`"BbëtBeÆÆBh¢Bk}iBnX»Bq4
+Bt]Bvê¯ByÆB|¡RB|Ë¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B2SrB5'ÞB80B:ÞB=¹ÓB@%BCpwBFKÈBI'BLlBNÝœBQ¹BTaBWo²BZKB]&UB`§BbÜùBežJBhBknîBnJ?Bq%Bt ãBvÜ4By·
+B|×B|Œ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B7ûB:ÐB=«XB@ªBCaûBF=MBIBKóðBNÏBBQªBT
+åBWa7BZ<B]ÚB_ó,BbÎ}Be©ÏBh
+!Bk`rBn;ÄBqBsògBvÍ¹By©
+B|\B|®¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B=£ÂB@x.BCSBF.ÒBI
+#BKåuBNÀÇBQBTwjBWRŒBZ.
+B]	_B_ä±BbÀBeTBhv¥BkQ÷Bn-IBqBsãìBv¿>ByB|uáB|¥¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BCKéBF UBHû§BKÖùBN²JBQBThîBWD?BZB\úãB_Ö4Bb±BeØBhh)BkC{Bn
+ÌBpú
+BsÕpBv°ÁByB|geB|)¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BHôBKÈ}BN£ÏBQ!BTZrBW5ÄBZB\ìgB_Ç¹Bb£
+Be~\BhY®Bk5 BnQBpë£BsÆôBv¢FBy}B|XéB|®¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BN9BQp¥BTK÷BW'IBZB\ÝìB_¹>BbBeoáBhK3Bk&BnÖBpÝ(BsžyBvËByo
+B|JnB|t3¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BTDaBWÍBYôB\ÏqB_ªÂBbBeafBh<·Bk	Bmó[BpÎ¬Bs©þBv
+PBy`¡B|;óB|e·¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BYìB\ÀôB_FBbwBeRéBh.;Bk	BmäÞBpÀ0BsBvvÓByR%B|-wB|W<¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B_°Bbi
+BeDnBhÀBjûBmÖcBp±µBsBvhXByCªB|
+ûB|HÁ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  Be<ØBhDBjìBmÇèBp£9Bs~BvYÝBy5.B|B|:F¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  Bjå Bm¹lBpŸBspBvKaBy&³B|B|+Ê¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  Bp'BsaBv<åBy7B{óB|
+O¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  Bv5OBy	»B{å
+B|Ô¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B{ÝwB| X¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                  -32 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   64 / length of data axis 1                          NAXIS2  =                   64 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 <#×
+<£×
+<õÂ=#×
+=LÌÍ=uÂ=\)=£×
+=žQì=ÌÌÍ=áG®=õÂ>
+ž>\)>>#×
+>.{>8Qì>B\>LÌÍ>W
+=>aG®>k
+>uÂ>  >
+
+ž>=q>\)>zá>>žR>£×
+>šõÃ>®{>³33>žQì>œp€>Â\>Ç®>ÌÌÍ>Ñë
+>×
+=>Ü(ö>áG®>æff>ë
+>ð£×>õÂ>úáH?   ?\?
+ž?®?
+=q?
+ÌÍ?\)?ë
+?zá?
+=??
+(ö?
+žR?!G®?  ?G®?\?×
+?
+
+ž?ff?®?õÃ?=q?
+?ÌÍ?{?\)?£×?ë
+?33?zá?Â?
+>?Qì??áH?(ö?p€?žR?   ?¡G®?¢\?£×
+?¥
+ž?Šff?§®?šõÂ?ª=q?«
+?¬ÌÍ?®{?¯\)?°£×?±ë
+?³33?Žzá?µÂ?·
+>?žQì?¹?ºáH?Œ(ö?œp€?ŸžR?À  ?ÁG®?Â\?Ã×
+?Å
+ž?Æff?Ç®?ÈõÂ?Ê=p?Ë
+
+?ÌÌÍ?Î{?Ï\)?Ð£×@   @ £×@G®@ë
+@\@33@×
+@zá@
+ž@Â@ff@
+=@®@Qì@õÃ@	@
+=q@
+áH@
+
+@
+(ö@
+ÌÍ@
+p€@{@žR@\)@  @£×@G®@ë
+@\@33@×
+@zá@
+ž@Â@ff@
+>@®@Qì@õÂ@@=q@áH@
+@
+(ö@
+ÌÍ@
+p€@
+{@
+žR@\)@   @ £×@!G®@!ë
+@"\@#33@#×
+@$zá@%
+ž@%Â@&ff@'
+>@'®@(Qì@@  @@£×@AG®@Aë
+@B\@C33@C×
+@Dzá@E
+ž@EÂ@Fff@G
+=@G®@HQì@HõÃ@I@J=q@JáH@K
+@L(ö@LÌÍ@Mp€@N{@NžR@O\)@P  @P£×@QG®@Që
+@R\@S33@S×
+@Tzá@U
+ž@UÂ@Vff@W
+>@W®@XQì@XõÂ@Y@Z=q@ZáH@[
+@\(ö@\ÌÍ@]p€@^{@^žR@_\)@`  @`£×@aG®@aë
+@b\@c33@c×
+@dzá@e
+ž@eÂ@fff@g
+>@g®@hQì@  @Qì@£×@õÃ@G®@@ë
+@=q@\@áH@33@
+@×
+@(ö@zá@ÌÍ@
+
+ž@
+p€@
+Â@{@ff@žR@
+=@\)@®@  @Qì@£×@õÃ@G®@@ë
+@=q@\@áH@33@
+@×
+@(ö@zá@ÌÍ@
+ž@p€@Â@{@ff@žR@
+=@\)@®@  @Qì@£×@õÂ@G®@@ë
+@=q@\@áH@33@
+@×
+@(ö@   @ Qì@ £×@ õÃ@¡G®@¡@¡ë
+@¢=q@¢\@¢áH@£33@£
+@£×
+@€(ö@€zá@€ÌÍ@¥
+ž@¥p€@¥Â@Š{@Šff@ŠžR@§
+=@§\)@§®@š  @šQì@š£×@šõÃ@©G®@©@©ë
+@ª=q@ª\@ªáH@«33@«
+@«×
+@¬(ö@¬zá@¬ÌÍ@­
+ž@­p€@­Â@®{@®ff@®žR@¯
+=@¯\)@¯®@°  @°Qì@°£×@°õÂ@±G®@±@±ë
+@²=q@²\@²áH@³33@³
+@³×
+@Ž(ö@À  @ÀQì@À£×@ÀõÃ@ÁG®@Á@Áë
+@Â=q@Â\@ÂáH@Ã33@Ã
+@Ã×
+@Ä(ö@Äzá@ÄÌÍ@Å
+ž@Åp€@ÅÂ@Æ{@Æff@ÆžR@Ç
+=@Ç\)@Ç®@È  @ÈQì@È£×@ÈõÃ@ÉG®@É@Éë
+@Ê=q@Ê\@ÊáH@Ë33@Ë
+@Ë×
+@Ì(ö@Ìzá@ÌÌÍ@Í
+ž@Íp€@ÍÂ@Î{@Îff@ÎžR@Ï
+=@Ï\)@Ï®@Ð  @ÐQì@Ð£×@ÐõÂ@ÑG®@Ñ@Ñë
+@Ò=q@Ò\@ÒáH@Ó33@Ó
+@Ó×
+@Ô(ö@à  @àQì@à£×@àõÃ@áG®@á@áë
+@â=q@â\@âáH@ã33@ã
+@ã×
+@ä(ö@äzá@äÌÍ@å
+ž@åp€@åÂ@æ{@æff@æžR@ç
+=@ç\)@ç®@è  @èQì@è£×@èõÃ@éG®@é@éë
+@ê=q@ê\@êáH@ë33@ë
+@ë×
+@ì(ö@ìzá@ìÌÍ@í
+ž@íp€@íÂ@î{@îff@îžR@ï
+=@ï\)@ï®@ð  @ðQì@ð£×@ðõÂ@ñG®@ñ@ñë
+@ò=q@ò\@òáH@ó33@ó
+@ó×
+@ô(öA   A (öA QìA záA £×A ÌÍA õÃA
+žAG®Ap€AAÂAë
+A{A=qAffA\AžRAáHA
+=A33A\)A
+A®A×
+A  A(öAQìAzáA£×AÌÍAõÃA
+žAG®Ap€AAÂAë
+A{A=qAffA\AžRAáHA
+=A33A\)A
+A®A×
+A  A(öAQìAzáA£×AÌÍAõÃA	
+žA	G®A	p€A	A	ÂA	ë
+A
+{A  A(öAQìAzáA£×AÌÍAõÃA
+žAG®Ap€AAÂAë
+A{A=qAffA\AžRAáHA
+=A33A\)A
+A®A×
+A  A(öAQìAzáA£×AÌÍAõÃA
+žAG®Ap€AAÂAë
+A{A=qAffA\AžRAáHA
+=A33A\)A
+A®A×
+A  A(öAQìAzáA£×AÌÍAõÃA
+žAG®Ap€AAÂAë
+A{A   A (öA QìA záA £×A ÌÍA õÃA!
+žA!G®A!p€A!A!ÂA!ë
+A"{A"=qA"ffA"\A"žRA"áHA#
+=A#33A#\)A#
+A#®A#×
+A$  A$(öA$QìA$záA$£×A$ÌÍA$õÃA%
+žA%G®A%p€A%A%ÂA%ë
+A&{A&=qA&ffA&\A&žRA&áHA'
+=A'33A'\)A'
+A'®A'×
+A(  A((öA(QìA(záA(£×A(ÌÍA(õÃA)
+žA)G®A)p€A)A)ÂA)ë
+A*{A0  A0(öA0QìA0záA0£×A0ÌÍA0õÃA1
+žA1G®A1p€A1A1ÂA1ë
+A2{A2=qA2ffA2\A2žRA2áHA3
+=A333A3\)A3
+A3®A3×
+A4  A4(öA4QìA4záA4£×A4ÌÍA4õÃA5
+žA5G®A5p€A5A5ÂA5ë
+A6{A6=qA6ffA6\A6žRA6áHA7
+=A733A7\)A7
+A7®A7×
+A8  A8(öA8QìA8záA8£×A8ÌÍA8õÃA9
+žA9G®A9p€A9A9ÂA9ë
+A:{A@  A@(öA@QìA@záA@£×A@ÌÍA@õÃAA
+žAAG®AAp€AAAAÂAAë
+AB{AB=qABffAB\ABžRABáHAC
+=AC33AC\)AC
+AC®AC×
+AD  AD(öADQìADzáAD£×ADÌÍADõÃAE
+žAEG®AEp€AEAEÂAEë
+AF{AF=qAFffAF\AFžRAFáHAG
+=AG33AG\)AG
+AG®AG×
+AH  AH(öAHQìAHzáAH£×AHÌÍAHõÃAI
+žAIG®AIp€AIAIÂAIë
+AJ{AP  AP(öAPQìAPzáAP£×APÌÍAPõÃAQ
+žAQG®AQp€AQAQÂAQë
+AR{AR=qARffAR\ARžRARáHAS
+=AS33AS\)AS
+AS®AS×
+AT  AT(öATQìATzáAT£×ATÌÍATõÃAU
+žAUG®AUp€AUAUÂAUë
+AV{AV=qAVffAV\AVžRAVáHAW
+=AW33AW\)AW
+AW®AW×
+AX  AX(öAXQìAXzáAX£×AXÌÍAXõÃAY
+žAYG®AYp€AYAYÂAYë
+AZ{A`  A`(öA`QìA`záA`£×A`ÌÍA`õÃAa
+žAaG®Aap€AaAaÂAaë
+Ab{Ab=qAbffAb\AbžRAbáHAc
+=Ac33Ac\)Ac
+Ac®Ac×
+Ad  Ad(öAdQìAdzáAd£×AdÌÍAdõÃAe
+žAeG®Aep€AeAeÂAeë
+Af{Af=qAfffAf\AfžRAfáHAg
+=Ag33Ag\)Ag
+Ag®Ag×
+Ah  Ah(öAhQìAhzáAh£×AhÌÍAhõÃAi
+žAiG®Aip€AiAiÂAië
+Aj{Ap  Ap(öApQìApzáAp£×ApÌÍApõÃAq
+žAqG®Aqp€AqAqÂAqë
+Ar{Ar=qArffAr\AržRAráHAs
+=As33As\)As
+As®As×
+At  At(öAtQìAtzáAt£×AtÌÍAtõÃAu
+žAuG®Aup€AuAuÂAuë
+Av{Av=qAvffAv\AvžRAváHAw
+=Aw33Aw\)Aw
+Aw®Aw×
+Ax  Ax(öAxQìAxzáAx£×AxÌÍAxõÃAy
+žAyG®Ayp€AyAyÂAyë
+Az{A  A{A(öA=qAQìAffAzáA\A£×AžRAÌÍAáHAõÃA
+=A
+žA33AG®A\)Ap€A
+AA®AÂA×
+Aë
+A  A{A(öA=qAQìAffAzáA\A£×AžRAÌÍAáHAõÃA
+=A
+žA33AG®A\)Ap€A
+AA®AÂA×
+Aë
+A  A{A(öA=qAQìAffAzáA\A£×AžRAÌÍAáHAõÃA
+
+=A  A{A(öA=qAQìAffAzáA\A£×AžRAÌÍAáHAõÃA
+=A
+žA33AG®A\)Ap€A
+AA®AÂA×
+Aë
+A  A{A(öA=qAQìAffAzáA\A£×AžRAÌÍAáHAõÃA
+=A
+žA33AG®A\)Ap€A
+AA®AÂA×
+Aë
+A  A{A(öA=qAQìAffAzáA\A£×AžRAÌÍAáHAõÃA
+=A  A{A(öA=qAQìAffAzáA\A£×AžRAÌÍAáHAõÃA
+=A
+žA33AG®A\)Ap€A
+AA®AÂA×
+Aë
+A  A{A(öA=qAQìAffAzáA\A£×AžRAÌÍAáHAõÃA
+=A
+žA33AG®A\)Ap€A
+AA®AÂA×
+Aë
+A  A{A(öA=qAQìAffAzáA\A£×AžRAÌÍAáHAõÃA
+=A  A{A(öA=qAQìAffAzáA\A£×AžRAÌÍAáHAõÃA
+=A
+žA33AG®A\)Ap€A
+AA®AÂA×
+Aë
+A  A{A(öA=qAQìAffAzáA\A£×AžRAÌÍAáHAõÃA
+=A
+žA33AG®A\)Ap€A
+AA®AÂA×
+Aë
+A  A{A(öA=qAQìAffAzáA\A£×AžRAÌÍAáHAõÃA
+=A   A {A (öA =qA QìA ffA záA \A £×A žRA ÌÍA áHA õÃA¡
+=A¡
+žA¡33A¡G®A¡\)A¡p€A¡
+A¡A¡®A¡ÂA¡×
+A¡ë
+A¢  A¢{A¢(öA¢=qA¢QìA¢ffA¢záA¢\A¢£×A¢žRA¢ÌÍA¢áHA¢õÃA£
+=A£
+žA£33A£G®A£\)A£p€A£
+A£A£®A£ÂA£×
+A£ë
+A€  A€{A€(öA€=qA€QìA€ffA€záA€\A€£×A€žRA€ÌÍA€áHA€õÃA¥
+=Aš  Aš{Aš(öAš=qAšQìAšffAšzáAš\Aš£×AšžRAšÌÍAšáHAšõÃA©
+=A©
+žA©33A©G®A©\)A©p€A©
+A©A©®A©ÂA©×
+A©ë
+Aª  Aª{Aª(öAª=qAªQìAªffAªzáAª\Aª£×AªžRAªÌÍAªáHAªõÃA«
+=A«
+žA«33A«G®A«\)A«p€A«
+A«A«®A«ÂA«×
+A«ë
+A¬  A¬{A¬(öA¬=qA¬QìA¬ffA¬záA¬\A¬£×A¬žRA¬ÌÍA¬áHA¬õÃA­
+=A°  A°{A°(öA°=qA°QìA°ffA°záA°\A°£×A°žRA°ÌÍA°áHA°õÃA±
+=A±
+žA±33A±G®A±\)A±p€A±
+A±A±®A±ÂA±×
+A±ë
+A²  A²{A²(öA²=qA²QìA²ffA²záA²\A²£×A²žRA²ÌÍA²áHA²õÃA³
+=A³
+žA³33A³G®A³\)A³p€A³
+A³A³®A³ÂA³×
+A³ë
+AŽ  AŽ{AŽ(öAŽ=qAŽQìAŽffAŽzáAŽ\AŽ£×AŽžRAŽÌÍAŽáHAŽõÃAµ
+=Až  Až{Až(öAž=qAžQìAžffAžzáAž\Až£×AžžRAžÌÍAžáHAžõÃA¹
+=A¹
+žA¹33A¹G®A¹\)A¹p€A¹
+A¹A¹®A¹ÂA¹×
+A¹ë
+Aº  Aº{Aº(öAº=qAºQìAºffAºzáAº\Aº£×AºžRAºÌÍAºáHAºõÃA»
+=A»
+žA»33A»G®A»\)A»p€A»
+A»A»®A»ÂA»×
+A»ë
+AŒ  AŒ{AŒ(öAŒ=qAŒQìAŒffAŒzáAŒ\AŒ£×AŒžRAŒÌÍAŒáHAŒõÃAœ
+=AÀ  AÀ{AÀ(öAÀ=qAÀQìAÀffAÀzáAÀ\AÀ£×AÀžRAÀÌÍAÀáHAÀõÃAÁ
+=AÁ
+žAÁ33AÁG®AÁ\)AÁp€AÁ
+AÁAÁ®AÁÂAÁ×
+AÁë
+AÂ  AÂ{AÂ(öAÂ=qAÂQìAÂffAÂzáAÂ\AÂ£×AÂžRAÂÌÍAÂáHAÂõÃAÃ
+=AÃ
+žAÃ33AÃG®AÃ\)AÃp€AÃ
+AÃAÃ®AÃÂAÃ×
+AÃë
+AÄ  AÄ{AÄ(öAÄ=qAÄQìAÄffAÄzáAÄ\AÄ£×AÄžRAÄÌÍAÄáHAÄõÃAÅ
+=AÈ  AÈ{AÈ(öAÈ=qAÈQìAÈffAÈzáAÈ\AÈ£×AÈžRAÈÌÍAÈáHAÈõÃAÉ
+=AÉ
+žAÉ33AÉG®AÉ\)AÉp€AÉ
+AÉAÉ®AÉÂAÉ×
+AÉë
+AÊ  AÊ{AÊ(öAÊ=qAÊQìAÊffAÊzáAÊ\AÊ£×AÊžRAÊÌÍAÊáHAÊõÃAË
+=AË
+žAË33AËG®AË\)AËp€AË
+AËAË®AËÂAË×
+AËë
+AÌ  AÌ{AÌ(öAÌ=qAÌQìAÌffAÌzáAÌ\AÌ£×AÌžRAÌÌÍAÌáHAÌõÃAÍ
+=AÐ  AÐ{AÐ(öAÐ=qAÐQìAÐffAÐzáAÐ\AÐ£×AÐžRAÐÌÍAÐáHAÐõÃAÑ
+=AÑ
+žAÑ33AÑG®AÑ\)AÑp€AÑ
+AÑAÑ®AÑÂAÑ×
+AÑë
+AÒ  AÒ{AÒ(öAÒ=qAÒQìAÒffAÒzáAÒ\AÒ£×AÒžRAÒÌÍAÒáHAÒõÃAÓ
+=AÓ
+žAÓ33AÓG®AÓ\)AÓp€AÓ
+AÓAÓ®AÓÂAÓ×
+AÓë
+AÔ  AÔ{AÔ(öAÔ=qAÔQìAÔffAÔzáAÔ\AÔ£×AÔžRAÔÌÍAÔáHAÔõÃAÕ
+=AØ  AØ{AØ(öAØ=qAØQìAØffAØzáAØ\AØ£×AØžRAØÌÍAØáHAØõÃAÙ
+=AÙ
+žAÙ33AÙG®AÙ\)AÙp€AÙ
+AÙAÙ®AÙÂAÙ×
+AÙë
+AÚ  AÚ{AÚ(öAÚ=qAÚQìAÚffAÚzáAÚ\AÚ£×AÚžRAÚÌÍAÚáHAÚõÃAÛ
+=AÛ
+žAÛ33AÛG®AÛ\)AÛp€AÛ
+AÛAÛ®AÛÂAÛ×
+AÛë
+AÜ  AÜ{AÜ(öAÜ=qAÜQìAÜffAÜzáAÜ\AÜ£×AÜžRAÜÌÍAÜáHAÜõÃAÝ
+=Aà  Aà{Aà(öAà=qAàQìAàffAàzáAà\Aà£×AàžRAàÌÍAàáHAàõÃAá
+=Aá
+žAá33AáG®Aá\)Aáp€Aá
+AáAá®AáÂAá×
+Aáë
+Aâ  Aâ{Aâ(öAâ=qAâQìAâffAâzáAâ\Aâ£×AâžRAâÌÍAâáHAâõÃAã
+=Aã
+žAã33AãG®Aã\)Aãp€Aã
+AãAã®AãÂAã×
+Aãë
+Aä  Aä{Aä(öAä=qAäQìAäffAäzáAä\Aä£×AäžRAäÌÍAäáHAäõÃAå
+=Aè  Aè{Aè(öAè=qAèQìAèffAèzáAè\Aè£×AèžRAèÌÍAèáHAèõÃAé
+=Aé
+žAé33AéG®Aé\)Aép€Aé
+AéAé®AéÂAé×
+Aéë
+Aê  Aê{Aê(öAê=qAêQìAêffAêzáAê\Aê£×AêžRAêÌÍAêáHAêõÃAë
+=Aë
+žAë33AëG®Aë\)Aëp€Aë
+AëAë®AëÂAë×
+Aëë
+Aì  Aì{Aì(öAì=qAìQìAìffAìzáAì\Aì£×AìžRAìÌÍAìáHAìõÃAí
+=Að  Að{Að(öAð=qAðQìAðffAðzáAð\Að£×AðžRAðÌÍAðáHAðõÃAñ
+=Añ
+žAñ33AñG®Añ\)Añp€Añ
+AñAñ®AñÂAñ×
+Añë
+Aò  Aò{Aò(öAò=qAòQìAòffAòzáAò\Aò£×AòžRAòÌÍAòáHAòõÃAó
+=Aó
+žAó33AóG®Aó\)Aóp€Aó
+AóAó®AóÂAó×
+Aóë
+Aô  Aô{Aô(öAô=qAôQìAôffAôzáAô\Aô£×AôžRAôÌÍAôáHAôõÃAõ
+=Aø  Aø{Aø(öAø=qAøQìAøffAøzáAø\Aø£×AøžRAøÌÍAøáHAøõÃAù
+=Aù
+žAù33AùG®Aù\)Aùp€Aù
+AùAù®AùÂAù×
+Aùë
+Aú  Aú{Aú(öAú=qAúQìAúffAúzáAú\Aú£×AúžRAúÌÍAúáHAúõÃAû
+=Aû
+žAû33AûG®Aû\)Aûp€Aû
+AûAû®AûÂAû×
+Aûë
+Aü  Aü{Aü(öAü=qAüQìAüffAüzáAü\Aü£×AüžRAüÌÍAüáHAüõÃAý
+=B   B 
+=B {B 
+žB (öB 33B =qB G®B QìB \)B ffB p€B záB 
+B \B B £×B ®B žRB ÂB ÌÍB ×
+B áHB ë
+B õÃB  B
+=B{B
+žB(öB33B=qBG®BQìB\)BffBp€BzáB
+B\BB£×B®BžRBÂBÌÍB×
+BáHBë
+BõÃB  B
+=B{B
+žB(öB33B=qBG®BQìB\)BffBp€BzáB
+B  B
+=B{B
+žB(öB33B=qBG®BQìB\)BffBp€BzáB
+B\BB£×B®BžRBÂBÌÍB×
+BáHBë
+BõÃB  B
+=B{B
+žB(öB33B=qBG®BQìB\)BffBp€BzáB
+B\BB£×B®BžRBÂBÌÍB×
+BáHBë
+BõÃB  B
+=B{B
+žB(öB33B=qBG®BQìB\)BffBp€BzáB
+B  B
+=B{B
+žB(öB33B=qBG®BQìB\)BffBp€BzáB
+B\BB£×B®BžRBÂBÌÍB×
+BáHBë
+BõÃB	  B	
+=B	{B	
+žB	(öB	33B	=qB	G®B	QìB	\)B	ffB	p€B	záB	
+B	\B	B	£×B	®B	žRB	ÂB	ÌÍB	×
+B	áHB	ë
+B	õÃB
+  B
+
+=B
+{B
+
+žB
+(öB
+33B
+=qB
+G®B
+QìB
+\)B
+ffB
+p€B
+záB
+
+B
+  B
+
+=B
+{B
+
+žB
+(öB
+33B
+=qB
+G®B
+QìB
+\)B
+ffB
+p€B
+záB
+
+B
+\B
+B
+£×B
+®B
+žRB
+ÂB
+ÌÍB
+×
+B
+áHB
+ë
+B
+õÃB
+  B
+=B
+{B
+
+žB
+(öB
+33B
+=qB
+G®B
+QìB
+\)B
+ffB
+p€B
+záB
+
+B
+\B
+B
+£×B
+®B
+žRB
+ÂB
+ÌÍB
+×
+B
+áHB
+ë
+B
+õÃB  B
+=B{B
+žB(öB33B=qBG®BQìB\)BffBp€BzáB
+B  B
+=B{B
+žB(öB33B=qBG®BQìB\)BffBp€BzáB
+B\BB£×B®BžRBÂBÌÍB×
+BáHBë
+BõÃB  B
+=B{B
+žB(öB33B=qBG®BQìB\)BffBp€BzáB
+B\BB£×B®BžRBÂBÌÍB×
+BáHBë
+BõÃB  B
+=B{B
+žB(öB33B=qBG®BQìB\)BffBp€BzáB
+B  B
+=B{B
+žB(öB33B=qBG®BQìB\)BffBp€BzáB
+B\BB£×B®BžRBÂBÌÍB×
+BáHBë
+BõÃB  B
+=B{B
+žB(öB33B=qBG®BQìB\)BffBp€BzáB
+B\BB£×B®BžRBÂBÌÍB×
+BáHBë
+BõÃB  B
+=B{B
+žB(öB33B=qBG®BQìB\)BffBp€BzáB
+B  B
+=B{B
+žB(öB33B=qBG®BQìB\)BffBp€BzáB
+B\BB£×B®BžRBÂBÌÍB×
+BáHBë
+BõÃB  B
+=B{B
+žB(öB33B=qBG®BQìB\)BffBp€BzáB
+B\BB£×B®BžRBÂBÌÍB×
+BáHBë
+BõÃB  B
+=B{B
+žB(öB33B=qBG®BQìB\)BffBp€BzáB
+B
+  B
+
+=B
+{B
+
+žB
+(öB
+33B
+=qB
+G®B
+QìB
+\)B
+ffB
+p€B
+záB
+
+B
+\B
+B
+£×B
+®B
+žRB
+ÂB
+ÌÍB
+×
+B
+áHB
+ë
+B
+õÃB
+  B
+
+=B
+{B
+
+žB
+(öB
+33B
+=qB
+G®B
+QìB
+\)B
+ffB
+p€B
+záB
+
+B
+\B
+B
+£×B
+®B
+žRB
+ÂB
+ÌÍB
+×
+B
+áHB
+ë
+B
+õÃB
+  B
+
+=B
+{B
+
+žB
+(öB
+33B
+=qB
+G®B
+QìB
+\)B
+ffB
+p€B
+záB
+
+B   B 
+=B {B 
+žB (öB 33B =qB G®B QìB \)B ffB p€B záB 
+B \B B £×B ®B žRB ÂB ÌÍB ×
+B áHB ë
+B õÃB!  B!
+=B!{B!
+žB!(öB!33B!=qB!G®B!QìB!\)B!ffB!p€B!záB!
+B!\B!B!£×B!®B!žRB!ÂB!ÌÍB!×
+B!áHB!ë
+B!õÃB"  B"
+=B"{B"
+žB"(öB"33B"=qB"G®B"QìB"\)B"ffB"p€B"záB"
+B$  B$
+=B${B$
+žB$(öB$33B$=qB$G®B$QìB$\)B$ffB$p€B$záB$
+B$\B$B$£×B$®B$žRB$ÂB$ÌÍB$×
+B$áHB$ë
+B$õÃB%  B%
+=B%{B%
+žB%(öB%33B%=qB%G®B%QìB%\)B%ffB%p€B%záB%
+B%\B%B%£×B%®B%žRB%ÂB%ÌÍB%×
+B%áHB%ë
+B%õÃB&  B&
+=B&{B&
+žB&(öB&33B&=qB&G®B&QìB&\)B&ffB&p€B&záB&
+B(  B(
+=B({B(
+žB((öB(33B(=qB(G®B(QìB(\)B(ffB(p€B(záB(
+B(\B(B(£×B(®B(žRB(ÂB(ÌÍB(×
+B(áHB(ë
+B(õÃB)  B)
+=B){B)
+žB)(öB)33B)=qB)G®B)QìB)\)B)ffB)p€B)záB)
+B)\B)B)£×B)®B)žRB)ÂB)ÌÍB)×
+B)áHB)ë
+B)õÃB*  B*
+=B*{B*
+žB*(öB*33B*=qB*G®B*QìB*\)B*ffB*p€B*záB*
+B,  B,
+=B,{B,
+žB,(öB,33B,=qB,G®B,QìB,\)B,ffB,p€B,záB,
+B,\B,B,£×B,®B,žRB,ÂB,ÌÍB,×
+B,áHB,ë
+B,õÃB-  B-
+=B-{B-
+žB-(öB-33B-=qB-G®B-QìB-\)B-ffB-p€B-záB-
+B-\B-B-£×B-®B-žRB-ÂB-ÌÍB-×
+B-áHB-ë
+B-õÃB.  B.
+=B.{B.
+žB.(öB.33B.=qB.G®B.QìB.\)B.ffB.p€B.záB.
+B0  B0
+=B0{B0
+žB0(öB033B0=qB0G®B0QìB0\)B0ffB0p€B0záB0
+B0\B0B0£×B0®B0žRB0ÂB0ÌÍB0×
+B0áHB0ë
+B0õÃB1  B1
+=B1{B1
+žB1(öB133B1=qB1G®B1QìB1\)B1ffB1p€B1záB1
+B1\B1B1£×B1®B1žRB1ÂB1ÌÍB1×
+B1áHB1ë
+B1õÃB2  B2
+=B2{B2
+žB2(öB233B2=qB2G®B2QìB2\)B2ffB2p€B2záB2
+B4  B4
+=B4{B4
+žB4(öB433B4=qB4G®B4QìB4\)B4ffB4p€B4záB4
+B4\B4B4£×B4®B4žRB4ÂB4ÌÍB4×
+B4áHB4ë
+B4õÃB5  B5
+=B5{B5
+žB5(öB533B5=qB5G®B5QìB5\)B5ffB5p€B5záB5
+B5\B5B5£×B5®B5žRB5ÂB5ÌÍB5×
+B5áHB5ë
+B5õÃB6  B6
+=B6{B6
+žB6(öB633B6=qB6G®B6QìB6\)B6ffB6p€B6záB6
+B8  B8
+=B8{B8
+žB8(öB833B8=qB8G®B8QìB8\)B8ffB8p€B8záB8
+B8\B8B8£×B8®B8žRB8ÂB8ÌÍB8×
+B8áHB8ë
+B8õÃB9  B9
+=B9{B9
+žB9(öB933B9=qB9G®B9QìB9\)B9ffB9p€B9záB9
+B9\B9B9£×B9®B9žRB9ÂB9ÌÍB9×
+B9áHB9ë
+B9õÃB:  B:
+=B:{B:
+žB:(öB:33B:=qB:G®B:QìB:\)B:ffB:p€B:záB:
+B<  B<
+=B<{B<
+žB<(öB<33B<=qB<G®B<QìB<\)B<ffB<p€B<záB<
+B<\B<B<£×B<®B<žRB<ÂB<ÌÍB<×
+B<áHB<ë
+B<õÃB=  B=
+=B={B=
+žB=(öB=33B==qB=G®B=QìB=\)B=ffB=p€B=záB=
+B=\B=B=£×B=®B=žRB=ÂB=ÌÍB=×
+B=áHB=ë
+B=õÃB>  B>
+=B>{B>
+žB>(öB>33B>=qB>G®B>QìB>\)B>ffB>p€B>záB>
+B@  B@
+=B@{B@
+žB@(öB@33B@=qB@G®B@QìB@\)B@ffB@p€B@záB@
+B@\B@B@£×B@®B@žRB@ÂB@ÌÍB@×
+B@áHB@ë
+B@õÃBA  BA
+=BA{BA
+žBA(öBA33BA=qBAG®BAQìBA\)BAffBAp€BAzáBA
+BA\BABA£×BA®BAžRBAÂBAÌÍBA×
+BAáHBAë
+BAõÃBB  BB
+=BB{BB
+žBB(öBB33BB=qBBG®BBQìBB\)BBffBBp€BBzáBB
+BD  BD
+=BD{BD
+žBD(öBD33BD=qBDG®BDQìBD\)BDffBDp€BDzáBD
+BD\BDBD£×BD®BDžRBDÂBDÌÍBD×
+BDáHBDë
+BDõÃBE  BE
+=BE{BE
+žBE(öBE33BE=qBEG®BEQìBE\)BEffBEp€BEzáBE
+BE\BEBE£×BE®BEžRBEÂBEÌÍBE×
+BEáHBEë
+BEõÃBF  BF
+=BF{BF
+žBF(öBF33BF=qBFG®BFQìBF\)BFffBFp€BFzáBF
+BH  BH
+=BH{BH
+žBH(öBH33BH=qBHG®BHQìBH\)BHffBHp€BHzáBH
+BH\BHBH£×BH®BHžRBHÂBHÌÍBH×
+BHáHBHë
+BHõÃBI  BI
+=BI{BI
+žBI(öBI33BI=qBIG®BIQìBI\)BIffBIp€BIzáBI
+BI\BIBI£×BI®BIžRBIÂBIÌÍBI×
+BIáHBIë
+BIõÃBJ  BJ
+=BJ{BJ
+žBJ(öBJ33BJ=qBJG®BJQìBJ\)BJffBJp€BJzáBJ
+BL  BL
+=BL{BL
+žBL(öBL33BL=qBLG®BLQìBL\)BLffBLp€BLzáBL
+BL\BLBL£×BL®BLžRBLÂBLÌÍBL×
+BLáHBLë
+BLõÃBM  BM
+=BM{BM
+žBM(öBM33BM=qBMG®BMQìBM\)BMffBMp€BMzáBM
+BM\BMBM£×BM®BMžRBMÂBMÌÍBM×
+BMáHBMë
+BMõÃBN  BN
+=BN{BN
+žBN(öBN33BN=qBNG®BNQìBN\)BNffBNp€BNzáBN
+BP  BP
+=BP{BP
+žBP(öBP33BP=qBPG®BPQìBP\)BPffBPp€BPzáBP
+BP\BPBP£×BP®BPžRBPÂBPÌÍBP×
+BPáHBPë
+BPõÃBQ  BQ
+=BQ{BQ
+žBQ(öBQ33BQ=qBQG®BQQìBQ\)BQffBQp€BQzáBQ
+BQ\BQBQ£×BQ®BQžRBQÂBQÌÍBQ×
+BQáHBQë
+BQõÃBR  BR
+=BR{BR
+žBR(öBR33BR=qBRG®BRQìBR\)BRffBRp€BRzáBR
+BT  BT
+=BT{BT
+žBT(öBT33BT=qBTG®BTQìBT\)BTffBTp€BTzáBT
+BT\BTBT£×BT®BTžRBTÂBTÌÍBT×
+BTáHBTë
+BTõÃBU  BU
+=BU{BU
+žBU(öBU33BU=qBUG®BUQìBU\)BUffBUp€BUzáBU
+BU\BUBU£×BU®BUžRBUÂBUÌÍBU×
+BUáHBUë
+BUõÃBV  BV
+=BV{BV
+žBV(öBV33BV=qBVG®BVQìBV\)BVffBVp€BVzáBV
+BX  BX
+=BX{BX
+žBX(öBX33BX=qBXG®BXQìBX\)BXffBXp€BXzáBX
+BX\BXBX£×BX®BXžRBXÂBXÌÍBX×
+BXáHBXë
+BXõÃBY  BY
+=BY{BY
+žBY(öBY33BY=qBYG®BYQìBY\)BYffBYp€BYzáBY
+BY\BYBY£×BY®BYžRBYÂBYÌÍBY×
+BYáHBYë
+BYõÃBZ  BZ
+=BZ{BZ
+žBZ(öBZ33BZ=qBZG®BZQìBZ\)BZffBZp€BZzáBZ
+B\  B\
+=B\{B\
+žB\(öB\33B\=qB\G®B\QìB\\)B\ffB\p€B\záB\
+B\\B\B\£×B\®B\žRB\ÂB\ÌÍB\×
+B\áHB\ë
+B\õÃB]  B]
+=B]{B]
+žB](öB]33B]=qB]G®B]QìB]\)B]ffB]p€B]záB]
+B]\B]B]£×B]®B]žRB]ÂB]ÌÍB]×
+B]áHB]ë
+B]õÃB^  B^
+=B^{B^
+žB^(öB^33B^=qB^G®B^QìB^\)B^ffB^p€B^záB^
+B`  B`
+=B`{B`
+žB`(öB`33B`=qB`G®B`QìB`\)B`ffB`p€B`záB`
+B`\B`B`£×B`®B`žRB`ÂB`ÌÍB`×
+B`áHB`ë
+B`õÃBa  Ba
+=Ba{Ba
+žBa(öBa33Ba=qBaG®BaQìBa\)BaffBap€BazáBa
+Ba\BaBa£×Ba®BažRBaÂBaÌÍBa×
+BaáHBaë
+BaõÃBb  Bb
+=Bb{Bb
+žBb(öBb33Bb=qBbG®BbQìBb\)BbffBbp€BbzáBb
+Bd  Bd
+=Bd{Bd
+žBd(öBd33Bd=qBdG®BdQìBd\)BdffBdp€BdzáBd
+Bd\BdBd£×Bd®BdžRBdÂBdÌÍBd×
+BdáHBdë
+BdõÃBe  Be
+=Be{Be
+žBe(öBe33Be=qBeG®BeQìBe\)BeffBep€BezáBe
+Be\BeBe£×Be®BežRBeÂBeÌÍBe×
+BeáHBeë
+BeõÃBf  Bf
+=Bf{Bf
+žBf(öBf33Bf=qBfG®BfQìBf\)BfffBfp€BfzáBf
+Bh  Bh
+=Bh{Bh
+žBh(öBh33Bh=qBhG®BhQìBh\)BhffBhp€BhzáBh
+Bh\BhBh£×Bh®BhžRBhÂBhÌÍBh×
+BháHBhë
+BhõÃBi  Bi
+=Bi{Bi
+žBi(öBi33Bi=qBiG®BiQìBi\)BiffBip€BizáBi
+Bi\BiBi£×Bi®BižRBiÂBiÌÍBi×
+BiáHBië
+BiõÃBj  Bj
+=Bj{Bj
+žBj(öBj33Bj=qBjG®BjQìBj\)BjffBjp€BjzáBj
+Bl  Bl
+=Bl{Bl
+žBl(öBl33Bl=qBlG®BlQìBl\)BlffBlp€BlzáBl
+Bl\BlBl£×Bl®BlžRBlÂBlÌÍBl×
+BláHBlë
+BlõÃBm  Bm
+=Bm{Bm
+žBm(öBm33Bm=qBmG®BmQìBm\)BmffBmp€BmzáBm
+Bm\BmBm£×Bm®BmžRBmÂBmÌÍBm×
+BmáHBmë
+BmõÃBn  Bn
+=Bn{Bn
+žBn(öBn33Bn=qBnG®BnQìBn\)BnffBnp€BnzáBn
+Bp  Bp
+=Bp{Bp
+žBp(öBp33Bp=qBpG®BpQìBp\)BpffBpp€BpzáBp
+Bp\BpBp£×Bp®BpžRBpÂBpÌÍBp×
+BpáHBpë
+BpõÃBq  Bq
+=Bq{Bq
+žBq(öBq33Bq=qBqG®BqQìBq\)BqffBqp€BqzáBq
+Bq\BqBq£×Bq®BqžRBqÂBqÌÍBq×
+BqáHBqë
+BqõÃBr  Br
+=Br{Br
+žBr(öBr33Br=qBrG®BrQìBr\)BrffBrp€BrzáBr
+Bt  Bt
+=Bt{Bt
+žBt(öBt33Bt=qBtG®BtQìBt\)BtffBtp€BtzáBt
+Bt\BtBt£×Bt®BtžRBtÂBtÌÍBt×
+BtáHBtë
+BtõÃBu  Bu
+=Bu{Bu
+žBu(öBu33Bu=qBuG®BuQìBu\)BuffBup€BuzáBu
+Bu\BuBu£×Bu®BužRBuÂBuÌÍBu×
+BuáHBuë
+BuõÃBv  Bv
+=Bv{Bv
+žBv(öBv33Bv=qBvG®BvQìBv\)BvffBvp€BvzáBv
+Bx  Bx
+=Bx{Bx
+žBx(öBx33Bx=qBxG®BxQìBx\)BxffBxp€BxzáBx
+Bx\BxBx£×Bx®BxžRBxÂBxÌÍBx×
+BxáHBxë
+BxõÃBy  By
+=By{By
+žBy(öBy33By=qByG®ByQìBy\)ByffByp€ByzáBy
+By\ByBy£×By®ByžRByÂByÌÍBy×
+ByáHByë
+ByõÃBz  Bz
+=Bz{Bz
+žBz(öBz33Bz=qBzG®BzQìBz\)BzffBzp€BzzáBz
+B|  B|
+=B|{B|
+žB|(öB|33B|=qB|G®B|QìB|\)B|ffB|p€B|záB|
+B|\B|B|£×B|®B|žRB|ÂB|ÌÍB|×
+B|áHB|ë
+B|õÃB}  B}
+=B}{B}
+žB}(öB}33B}=qB}G®B}QìB}\)B}ffB}p€B}záB}
+B}\B}B}£×B}®B}žRB}ÂB}ÌÍB}×
+B}áHB}ë
+B}õÃB~  B~
+=B~{B~
+žB~(öB~33B~=qB~G®B~QìB~\)B~ffB~p€B~záB~
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                  -32 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   91 / length of data axis 1                          NAXIS2  =                   91 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  =
+(Ð9±¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ?¹V:?=œ =(a<m<{¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  @7-@	ñâ?ºHþ?A\r=bn|<êxs¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  @Ø@dt\@7Šù@
+Ù?Œg?DûC=-Ë=/)S¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  @¶<@{b@±@e\@8@
+Á;?œç°?HÔ=«"U=ig¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  @ãZx@ÌŒ@¶Uí@ï<@@fCµ@9vR@
+šï?¿·?L8Š=Èâ=Á¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AMÚ@ùýÚ@ã)@Í0x@¶ÉÇ@ c@üf@g+i@:^@
+£?Á?O×x=åm=®xL¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A
+îxAAl3@úqµ@ä
+@Í€S@·=¢@ Öñ@p@@h
+@;Eº@xX?ÃUê?SvJ>ý=ËnÙ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A5A*@)A
+ÑAÙxAŠ @úå@ä~Þ@Î-@·±|@¡JË@ä@húÒ@<-o@`
+?Å%S?W>~C=èee¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AL/°A@àÃA5­kA*zAFºAaAà	@ûYa@äò°@Îÿ@ž%N@¡Ÿ@Wì@iâv@=@G°?Æô?Z³¬>
+ø>­÷¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AbÐNAWaALN	AA°A5çXA*³ÿA§AMNA	ö@ûÍ;@åf@ÎÿÙ@ž(@¢2w@ËÆ@jÊ*@=üÇ@/e?ÈÄ?^R~>,sÏ>)>¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AypìAn!ÿAbî§AW»NALöAATA6!EA*íìAºA<A	Sã@üA@åÚd@Ïs³@¹
+@¢ŠQ@?¡@k±ß@>ä|@?Ên?añO>:ï>€¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AÆAaOAyEAn[ìAc(AWõ;ALÁãAAA6[2A+'ÚAôAÁ(A	Ð@üŽï@æN>@Ïç@¹Ý@£,@³z@l@?Ì1@þÎ?ÌbÖ?e!>Ij[>.Ì¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AYA±AðA~DAyÉ.AnÕAcb}AX/$ALûÌAAÈtA6A+aÂA .jAûA	Ç¹@ý(Â@æÂ@Ð[`@¹ô®@£þ@'M@m8@@³Õ@æs?Î2?i.²>Wä£><¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A©dAíAh@AÎA4çA:AzAnÏÂAcjAXiAM5¹AB`A6ÏA+°A hWA4ÿA
+Š@ý@ç5ê@ÐÏ:@ºh@€Ø@'@nhì@A@Î'?Ð?lÍ
+>f_ê>KZ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A©ùŽA€R=AžA
+äA
+7AëAQÞAž1Az=Ao	°AcÖWAX¢þAMoŠAB<NA7õA+ÕA ¢DAnëA
+;@þv@ç©Å@ÑC@ºÜc@€u²@@oP¡@B>@µÛ?ÑÐñ?plW>tÛ1>Y¡¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AµJA¯¢AªàA€o4AÕA;ÚA¢.AAnÓAÕ'AzvõAoCAdDAXÜìAM©ABv;A7BâA,A Ü1AšÙA
+u@þP@è
+@Ñ¶î@»P=@€é@Û@p8U@Cjó@?Ó Z?t
+(>«<>h
+è¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AÀTAºòÝAµY0A¯¿Aª%×A€*Aò~AXÑA¿#A%wAÊAò
+Az°âAo}AdJ1AYÙAMãAB°'A7|ÏA,IwA!AâÆA
+¯m@þø*@èy@Ò*È@»Ä@¥]f@ö¶@q 	@DR§@
+D?ÕoÃ?w©ú>èà>v/¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AËê¢AÆC+AÀ©~A»ÒAµv%A¯ÜxAªBÌA€©AqAuÅAÜABlAš¿AAzêËAo·sAdAYPÁAN
+iABêA7¶¹A,`A!PA
+¯A
+éV@ÿkü@éK@Ò@Œ7ê@¥Ñ8@j@r®@E:K@lè?×?
+?{H>&>»¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A×:òAÑ{AËùÎAÆ`"AÀÆuA»,ÈAµ
+A¯ùoAª_ÁA€ÆA,hAŒAùA_bAÅ¶A,	A{$žAoñ_AdŸAY¯ANWWAC#þA7ð¥A,œMA!ôAVA
+#D@ÿßÖ@éy&@Ót@Œ«Ä@ŠE@Þb@rïb@F" @T?Ùt?~ç]>c§>¿_¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AâBAÜãËA×J
+AÑ°rAÌÅAÆ}AÀãlA»I¿Aµ°A°eAª|žA€ã
+AI_A¯²AA|YAâ¬AI A{^ŠAp+MAd÷õAYÄANCAC]ëA8*A,÷:A!ÃâAA
+]0A )Ø@éí @ÓO@œ@Šží@R<@s×@G	Ž@<Q?ÚÝÝ?C>¡K>ý¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AíÛAè4AânAÝ ÂA×gAÑÍhAÌ3ŒAÆAÁ aA»fµAµÍA°3\Aª¯A¥ AfVAÌ©A2üAPAÿ£AeöA{Ape:Ae1áAYþANË0ACØA8dA-1'A!ýÎAÊvA
+
+A cÆ@ê`Ú@Óú)@œx@§,Ç@Æ@tŸÌ@Gñh@$?Ü­F?>¥Þî>:Š¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  Aù+âAókAíêŸAèQAâ·eAÝ
+žA×
+AÑê_AÌP±AÆ·AÁ
+XA»¬AµéÿA°PRAª¶ŠA¥
+ùALAé AOóA¶FA
+AìA{ÒAp'AekÎAZ8vAO
+ACÑÅA8lA-kA"7ŒAdA
+Ñ
+A ²@êÔŽ@Ôn@ŸR@§ ¢@9ñ@uŠ@HÙ
+@
+
+º?Þ|¯?áé>­
+>xJ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B>AþÔ¹Aù;
+Aó¡`Aî³AènAâÔZAÝ:­A× ÿAÒSAÌmŠAÆÓúAÁ:MA»  A¶ôA°mGAªÓA¥9îA AAAlçAÓ:A9AáA|
+hApÙAe¥žAZr_AO?AD
+®A8ØVA-€þA"q¥A>LA
+
+ôA ×@ëH@ÔáÖ@Ÿ{%@št@­Ã@v$@IÀÁ@
+ó_?àK÷?±2>ŽYµ>Šµí¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  Bæ@BBE®Aþñ¯AùXAóŸVAî$ªAèýAâñOAÝW£A×œöAÒ$JAÌAÆððAÁWDA»œA¶#êA°>AªðA¥VäAœ7A#AÝAð1AVAŒØA|FVAqýAeß€AZ¬LAOxôADEA9CA-ÞêA"«Ax9A
+DáA@ëŒa@ÕU°@Ÿîÿ@šN@!@wuÙ@Jšv@
+Û?â`?>»Y>­ó¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B
+hB
+º¬BíÖB! BT)AÿŠAùtúAóÛMAîAAè§óAãFAÝtA×ÚíAÒA@AÌ§AÇ
+çAÁt:A»ÚA¶@áA°§4A«
+A¥sÚAÚ-A@AŠÔA
+(As{AÙÎA|CAqLêAfAZæ:AO²áADA9L0A.×A"åA²'A
+~ÏAKv@ì0;@ÕÉ@¿bÙ@šü)@x@x]@K*@
+ÂÇ?ãêÊ?P>ÂÔü>µ15¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B6BbÔB
+þB
+É(BüQB/{Bb¥Aÿ+AùïAóøCAî^AèÄêAã+=AÝA×÷äAÒ^7AÌÄAÇ*ÞAÁ1A»÷A¶]×A°Ä*A«*}A¥ÑA÷$A]xAÃËA*
+ArAöÅA|º0AqØAfSA[ &AOìÎAD¹uA9
+A.RÅA#mAìA
+žŒA
+c@ì€@Ö=e@¿ÖŽ@©p@	R@yEB@Lwß@ª|?åº2?m>Ê¡>ŒnÙ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BÞžB
+üB>&BqPB
+€yB
+×£B
+ÍB=öBq AÿHAù®æAô:Aî{AèáàAãH4AÝ®AØÚAÒ{.AÌáAÇGÔAÁ®'AŒzA¶zÎA°á!A«GtA¥­ÈA AznAàÂAGA­hA»A|ô
+AqÀÄAflA[ZAP&»ADócA9À
+A.²A#YZA&A
+ò©A¿P@íð@Ö±?@ÀJ@©ãÝ@},@z,ö@M_@ 1?ç?îÖ>ÑPD>Ã¬|¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B
+ßB³#BæMBwBL BÊB
+²ôB
+æ
+BGBLqBAÿeAùËÛAô2.AîAèþÕAãe(AÝË|AØ1ÏAÒ"AÌþuAÇdÈAÁË
+AŒ1oA¶ÂA°þA«diA¥ÊŒA 1AcAý¶Ad	AÊ\A0°A}.Aqú­AfÇUA[ýAP`¥AE-LA9ùôA.ÆA#CA_êA
+,Aù:@íÂ@×%@ÀŸ`@ªW¯@ðþ@{@NG8@!yÕ?éXå?Ÿ>Øh>Êê ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B$/B![KB
+uBÁBôÈB'òB[
+BEB
+ÁoB
+ôB'ÂBZìBAÿAùèÒAôO%AîµxAéÌAãAÝèrAØNÅAÒµAÍlAÇ¿AÁèAŒNfA¶Ž¹A±
+A«`A¥ç³A NAŽYA¬A AçSAMŠA}góAr4AgCA[ÍêAPAEg9A:3áA/ A#Í0AØA
+fA3&@íÿ@×ë@Á2:@ªË@dÙ@{üO@O.ì@"a?ë(M?>ßË
+>Ò'Ä¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B)×/B'sB$6B!iÇB
+ðBÐBDB6mBiBÁB
+ÏêB
+B6>BigBAÿtAúÈAôl
+AîÒoAé8ÂAãAÞhAØkŒAÒÒAÍ8bAÇ¶AÂ	AŒk\A¶Ñ°A±8A«VAŠ©A jüAÑPA7£AöAJAjA}¡áArnAg;0A\×APÔAE¡&A:mÎA/:vA$
+AÓÄA
+ lAm@îsv@Ø
+Å@ÁŠ@«?c@Ø³@|ä@P @#I>?ì÷·?\ñ>ç¯>Ùeh¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B/WB,«B)ÞÅB'ïB$EB!xBB
+«lBÞB¿BDéBxB«<B
+ÞfB
+BD¹BwâB«
+AÿŒkAú"¿AôAîïeAéUžAãŒ
+AÞ"_AØ²AÒïAÍUYAÇ»¬AÂ" AŒSA¶îŠA±TùA«»LAŠ! A óAîFATAºíA!@AA}ÛÎAršuAgu
+A\AÄAQlAEÛA:§»A/tbA$A
+A
+²A
+ÚYA§@îçQ@Ø@Âï@«³>@L@}Ëž@PþV@$0ó?îÇ ?,Z>îFT>à£
+¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B5'B2SÃB/íB,ºB)í@B' jB$SB!œB
+¹çBíB :BSdBB¹·B
+ìáB
+ 
+BS4B^B¹AÿÙbAú?µAôŠAï
+\Aér¯AãÙAÞ?VAØ¥©AÓ
+üAÍrPAÇØ£AÂ>öAŒ¥IA·
+A±qðA«ØCAŠ>A €êA
+=AqA×äA>7A€A~»ArâbAg¯
+A\{²AQHYAF A:ášA/®PA$z÷AGAFAàî@ï[+@Øôz@ÂÉ@¬'@Àg@~³l@Qæ
+@%§?ð?ûÄ>õù>çà°¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B:ÏŠB7ûêB5/B2b>B/gB,ÈB)û»B'.äB$bB!8B
+ÈaBûB.µBaÞBBÈ1B
+û[B
+.
+Ba®BØBÈAÿöVAú\ªAôÂýAï)PAé€Aãõ÷AÞ\JAØÂAÓ(ñAÍDAÇõAÂ[êAŒÂ>A·(A±äA«õ8AŠ[A ÁÞA(2A
+AôØA[,AÁ~A~O£As
+LAgèóA\µAQBAFNêA;A/è9A$ŽàAAN/A×@ïÎý@ÙhL@Ã@¬ê@49@@RÍ¯@& L?òeÒ?Ë
+>üÁ
+>ï
+U¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B@wÎB=€B:×<B8
+fB5=B2p¹B/£ãB,×
+B*
+6B'=`B$pB!£³B
+ÖÝB
+
+B=0BpYB£BÖ­B	ÖB
+= Bp*B£SBÖ}B 	§Aúy AôßôAïFGAé¬AäîAÞyAAØßAÓEçAÍ¬:AÈAÂxáAŒß4A·EA±«ÛA¬.AŠxA ÞÕAE(A«|AÎAx"AÞuA~AsV8Ah"àA\ïAQŒ/AF×A;U~A0"&A$îÍA»uA
+ATÄ@ðB×@ÙÜ&@Ãuu@­Ä@š@Ac@Sµc@&è ?ô5;?u?ÿ`>ö[ø¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BFöBCL:B@dB=²B:å·B8áB5L
+B24B/²^B,åB*±B'KÛB$B!².B
+åXB
+BK«B~ÕB±þBå(BRB
+K{B~¥B±ÏBäøB !AúAôüêAïc>AéÉAä/äAÞ7AØüAÓbÞAÍÉ1AÈ/AÂØAŒü+A·b~A±ÈÒA¬/%AŠxA ûÌAb
+AÈrA.ÅAAûlA~Ã~As&Ah\ÍA])uAQö
+AFÂÄA;kA0\A%(»AõbAÂ	A±@ð¶±@ÚP @ÃéO@­@î@µ=@T@'Ïµ?ö€?iÞ?2>ý¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BKÈ
+BHôbBF'BCZ¶B@ßB=Á	B:ô3B8'\B5ZB2°B/ÀÙB,ôB*'-B'ZVB$B!À©B
+óÓB
+&ýBZ&BPBÀzBó£B&ÍB
+Y÷B BÀIBósB &Aú³AõáAï4AéæAäLÚAÞ³.AÙAÓÔAÍæ(AÈL{AÂ²ÎAœ"A·uA±åÈA¬L
+AŠ²nA¡ÂAAåhAKŒA²A
+bA~ýkAsÊAhºA]cbAR0	AFü±A;ÉYA0 A%b§A/OAû÷AÈ@ñ*@ÚÃÛ@Ä]*@­öy@È@)@UÌ@(·i?÷Ô
+?9G?	=?k ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BQpFBNBKÏŽBIÞBF6BCi1B@[B=ÏB;®B85ØB5iB2+B/ÏUB-~B*5šB'hÑB$ûB!Ï%BNB
+5xBh¢BËBÎõBB5HB
+hqBBÎÅBîB 5AúÐAõ6×Aï*Aê~AäiÑAÞÐ$AÙ6xAÓËAÎ
+AÈirAÂÏÅAœ6A·lA²ŸA¬iAŠÏeA¡5žA
+A_Ah²AÏA
+5YA7XAt AhÐ§A]OARi÷AG6A<EA0ÏíA%Ai<A5äA@ñf@Û7µ@ÄÑ@®jS@¢@ò@Vl@)
+?ù£v? °?
+ÛÖ?
+r¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BWmBTD±BQwÛBN«BKÞ.BIXBFDBCw«B@ªÕB=ÝÿB;(B8DRB5w|B2ª¥B/ÝÏB-øB*D"B'wLB$ªuB!ÝBÉB
+CòBw
+BªFBÝoBBCÂB
+vìBªBÝ?BiB CAúíxAõSÌAïºAê rAäÆAÞíAÙSlAÓ¹ÀAÎ AÈfAÂìºAœS
+A·¹`A²³A¬AŠìZA¡R­A¹ ATA
+§AëúA
+RNAqAAt=éAi
+A]×8AR£ßAGpA<=/A1	ÖA%Ö~A£%AoÍA<t@ò8@Û«@ÅDÖ@®Þ%@wt@Ä@WT%@*Â?ûrŸ?¡×ù?zg?	©D¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B\ÀBYìÙBW BTS-BQVBN¹BKìªBIÓBFRýBC'B@¹PB=ìzB;€B8RÍB5
+÷B2¹ B/ìJB-tB*RB'
+ÇB$žñB!ìBDB
+RnB
+BžÀBëêBBR=B
+
+gBžBë»B
+åB RAû
+oAõpÂAï×Aê=iAä£ŒAß
+AÙpcAÓÖ¶AÎ=
+AÈ£\AÃ	°AœpA·ÖVA²<ªA¬¢ýA§	PA¡o€AÕ÷A<JA¢AñA
+oDA«.AtwÖAiD}A^%ARÝÍAGªtA<w
+A1CÃA&kAÝA©ºAvb@ò@Üa@Åž°@¯R @ëO@@X;Ù@+nv?ýB'?£§b?:?
+H¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BbhœB_B\È+BYûUBW.~BTašBQÒBNÇûBKû%BI.OBFaxBC¢B@ÇÌB=úõB;.B8aHB5rB2ÇB/úÅB--ïB*aB'BB$ÇlB!úB-¿B
+`èBBÇ<BúeB-B`¹B
+ãBÇ
+Bú6B-`B `Aû'fAõ¹Aïô
+AêZ`AäÀ³Aß'AÙZAÓó¬AÎZ AÈÀSAÃ&ŠAœúA·óMA²Y A¬¿ôA§&GA¡AòîAYAA¿A%çA
+:AåAt±ÃAi~kA^KASºAGäaA<±	A1}°A&JXA Aã§A°N@òùì@Ü<@Æ,@¯ÅÚ@_)@øx@Y#@,V+?ÿ?¥vË?ž
+?æè¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BhåBe=)BbpSB_£}B\ÖŠBZ	ÐBW<úBTp#BQ£MBNÖwBL	 BI<ÊBFoôBC£
+B@ÖGB>	pB;<B8oÄB5¢íB2ÖB0	AB-<jB*oB'¢ŸB$ÕçB"	B<:B
+odB¢BÕ·BáB<
+Bo5B
+¢^BÕB²B;ÛB oAûD\Aõª°AðAêwVAäÝªAßCüAÙªPAÔ£AÎvöAÈÝJAÃCAœ©ðAžDA²vA¬ÜêA§C>A¡©AäAv7AÜABÞA
+©1AAtë°AižXA^ÿASQ§AH
+NA<êöA1·A&EAPìA
+Aê<@ómÇ@Ý@Æ e@°9Ž@Ó@lR@Z
+B@-=ß@ p|?§F3?VÝ?
+¹¿  ¿  ¿  ¿  ¿  ¿  Bm¹
+BjåQBh{BeK¥Bb~ÎB_±øB\å"BZKBWKuBT~BQ±ÈBNäòBL
+BIKEBF~oBC±B@äÂB>ìB;KB8~?B5±iB2äB0ŒB-JæB*~B'±8B$äbB"BJµB
+}ßB±	Bä3B]BJB}°B
+°ÚBäB,BJVB }AûaSAõÇŠAð-úAêLAäú Aß`óAÙÇFAÔ-AÎíAÈú@AÃ`AœÆçAž-:A²A¬ùáA§`4A¡ÆA,ÚA.AùA_ÔA
+Æ(A,{Au%AiòEA^ŸìASAHX<A=$ãA1ñA&Ÿ2AÚAWA$)@óá¡@Ýzð@Ç?@°­@FÞ@à-@Zòö@.%@X1?©?
+õ¯?$¿  ¿  ¿  ¿  Bsa4BpxBmÀ¢BjóÌBh&õBeZBbIB_ÀrB\óBZ&ÆBWYïBTBQÀCBNólBL&BIY¿BFéBCÀB@ó<B>&fB;YB8¹B5¿ãB2ó
+B0&6B-Y_B*B'¿³B$òÜB"&BY0B
+ZB¿Bò­B%×BYB*B
+¿SBò}B%§BXÐB úAû~HAõäAðJîAê±AAåAß}èAÙä;AÔJAÎ°âAÉ5AÃ}AœãÜAžJ/A²°A­ÕA§}(A¡ã|AIÏA°"AvA|ÉA
+ã
+AIpAu_Aj,.A^øÖASÅ}AH$A=^ÌA2+tA&øAÄÃAkA^@ôUs@ÝîÂ@Ç@±!a@º°@Sÿ@[Ú@/
+8@?Õ?ªäæ?"B?Ã^¿  ¿  By	\Bv5 BshÊBpôBmÏ
+BkGBh5qBehBbÄB_ÎîB]BZ5ABWhkBTBQÎŸBOçBL5BIh;BFdBCÎBAžB>4áB;h
+B85B5Î^B3B04±B-gÛB*B'Î.B%XB"4Bg¬B
+ÕBÍÿB)B4RBg{B¥B
+ÍÏB	 øB4"BgLB uAû>AöAðgäAêÎ8Aå4AßÞAÚ2AÔg
+AÎÍØAÉ4,AÃAŸ ÒAžg%A²ÍxA­3ÌA§A¢ rAfÆAÍA3lAÀA AffAutAjfA_2ÂASÿjAHÌA=¹A2eaA'2	Aþ°AËWAÿ@ôÉN@Þb@Çûì@±;@.@ÇÙ@\ÂO@/ôí@'?¬ŽO?&3?b/B|  B{ÝÈByòBvD
+BswEBpªoBmÝBkÂBhCìBewBbª?B_ÝiB]BZCŒBWvæBTªBQÝ9BOcBLCBIv¶BF©àBCÝ	BA3B>C]B;vB8©¯B5ÜÙB3B0C,B-vVB*©B'ÜªB%ÔB"BýBv'B
+©QBÜzB£BBÍBu÷B© B
+ÜJB	tBBBuÇB šñAûž4Aö
+AðÛAêë.AåQAß·ÕAÚ
+(AÔ|AÎêÏAÉQ"AÃ·uAŸ
+ÈAž
+A²êoA­PÂA§·A¢
+iAŒAêAPcA¶¶A
+	A\AuÓ`Aj A_l°AT9WAIÿA=Ò§A2NA'kõA
+8AEAÑí@õ=(@ÞÖw@ÈoÆ@²	@¢e@
+;³@]ª@0Ü¢@??®ž?)Ñå¿  B|B{ìDBymBvRBs
+ÁBpžêBmìBk>BhRgBe
+Bbž»B_ëäB]BZR7BW
+aBTžBQëŽBO
+ÞBLRBI
+1BFž[BCë
+BA
+®B>Q×B;
+B8ž+B5ëTB3
+~B0QšB-ÒB*·üB'ë%B%
+OB"QyB¢B
+·ËBêõB
+BQHBrB·B
+êÅB	
+ïBQBBB ·lAûÕ+Aö;~Að¡ÒAë%AånxAßÔÌAÚ;AÔ¡rAÏÅAÉnAÃÔlAŸ:¿Až¡A³fA­m¹A§Ô
+A¢:`A ³AAmYAÓ¬A: A SAv
+NAjÙõA_ŠATsEAI?ìA>
+A2Ù;A'¥ãA
+rA?2A
+Ù@õ±@ßJQ@Èã¡@²|ð@>@
+¯@^¹@1ÄV@öó?¯vw¿  ¿  B|B{ú¿By-éBvaBs<BpÇfBmúBk-¹Bh`ãBe
+BbÇ6B_ú_B]-BZ`³BWÜBTÇBQú0BO-YBL`BI­BFÆÖBCùÿBA-)B>`SB;|B8ÆŠB5ùÐB3,úB0`$B-MB*ÆwB'ù¡B%,ÊB"_óB
+B
+ÆGBùpB,B_ÄBíBÆB
+ùAB	,jB_BŸB ÅçAûò"AöXuAðŸÈAë%
+AåoAßñÂAÚXAÔŸhAÏ$ŒAÉAÃñbAŸW¶AžŸ	A³$\A­°A§ñA¢WVAœ©A#üAPAð£AVöAœJAvG;AkãA_àAT­1AIyÙA>FA3)A'ßÐA
+¬wAyAEÇ@ö$Ý@ßŸ,@ÉWz@²ðÊ@@#h@_yn@2=¶¿  ¿  ¿  ¿  B|$B|	:By<dBvoBs¢·BpÕáBn	
+Bk<4Bho^Be¢BbÕ±B`ÛB]<BZo.BW¢XBTÕBR«BO;ÕBLnþBI¢'BFÕQBD{BA;€B>nÎB;¡øB8Õ"B6LB3;uB0nB-¡ÉB*ÔòB(B%;EB"noB¡B
+ÔÂBìB;Bn?B¡iBÔB
+ŒB	:æBnB¡9B ÔbAüAöulAðÛ¿AëBAåšeAàžAÚu
+AÔÛ_AÏA²AÉšAÄYAŸt¬AžÛ A³ASA­§ŠAš
+ùA¢tLAÚ A@óA§FA
+AsíAÚ@Av(AkMÏA`wATçAI³ÇA>nA3MA(œA
+æeA³
+AŽ@ö·@à2@ÉËU@³d€@ýó@`¿  ¿  ¿  ¿  ¿  ¿  B|3B|¶ByJßBv~	Bs±3Bpä\BnBkJ¯Bh}ÙBe±Bbä,B`VB]JBZ}©BW°ÓBTãýBR&BOJOBL}yBI°£BFãÌBDöBAJ B>}JB;°tB8ãB6ÇB3IñB0}B-°CB*ãmB(B%IÀB"|êB°B
+ã=BgBIB|ºB¯äBãB
+7B	IaB|B¯ŽB âÞAü,AöbAðøµAë_AåÅ\Aà+¯AÚAÔøVAÏ^©AÉÄüAÄ+PAŸ£Až÷öA³^IA­ÄAš*ðA¢CA÷A]êAÄ=A*AäA÷7Av»AkœA`TeAU!
+AIí³A>º[A3A(SªA
+ RAìúA¹¡@÷
+@à¥à@Ê?/@³¡T¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|AB|&/ByYYBvBs¿¬BpòÕBn%ÿBkY)BhRBe¿|BbòŠB`%ÏB]XùBZ#BW¿LBTòuBR%BOXÉBLòBI¿
+BFòFBD%pBAXB>ÃB;ŸíB8òB6%@B3XiB0B-ŸœB*ñæB(%B%X:B"cBŸB
+ñ·B$àBX
+B4BŸ]BñB
+$°B	WÚBBŸ-B ñWAüIAö¯TAñšAë{ûAåâNAàH¢AÚ®õAÕHAÏ{AÉáïAÄHBAŸ®A¹èA³{<A­áAšGâA¢®6AAzÜAá0AGA­×A)AvôûAkÁ¢A`IAUZñAJ'A>ô@A3ÀèA(A
+Z7A&ÞAó@÷[@àâ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|OÿB|4ªBygÔBvýBsÎ'BqQBn4zBkg€BhÎBeÍ÷Bc!B`4KB]gtBZBWÍÇBU ñBR4BOgDBLnBIÍBG ÂBD3ëBAgB>?B;ÍhB9 B63»B3fåB0B-Í8B+ bB(3B%fµB"ßBÍB
+ 2B3\Bf
+B¯BÌØB B
+3,B	fUBBÌšB ÿÒAüeøAöÌKAñ2AëòAåÿEAàeAÚËìAÕ2?AÏAÉþåAÄe8AŸËA¹1ßA³2A­þAšdÙA¢Ë,A1AÓAþ'AdyAÊÌA1 Aw.çAkûA`È7AUÞAJaA?..A3úÕA(Ç|A
+$A`ÌAÞ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|^zB|C%ByvOBv©yBsÜ¢BqÌBnBöBkvBh©IBeÜsBcB`BÅB]uïBZ©BWÜBBUlBRBBOuÀBLšêBIÜBG=BDBgBAuB>š¹B;ÛãB9
+B6B6B3u`B0šB-Û³B+ÝB(BB%u0B"šZBÛB
+­BA×Bu Bš*BÛTB}B
+A§B	tÐB§úBÛ$BMAüîAöéBAñOAëµèAæ
+<AàAÚèâAÕO5AÏµAÊÜAÄ/AŸèA¹NÖA³µ)A®|AšÐA¢è#ANwAŽÉA
+ApAçÃANAwhÕAl5|Aa$AUÎÌAJsA?hA44ÂA)jA
+²|¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|lõB|Q¡ByÊBv·ôBsë
+Bq
+GBnQqBkBh·ÄBeêíBc
+B`QAB]jBZ·BWêŸBU
+èBRQBO;BL·eBIêBG
+žBDPáBA
+B>·5B;ê^B9
+B6P²B3ÛB0·B-ê/B+
+XB(PB%¬B"¶ÕBéÿB
+
+(BPRB|B¶¥BéÏB
+øB
+P"B	LB¶uBéB
+ÉAüåA÷8AñlAëÒßAæ92Aà
+AÛØAÕl,AÏÒAÊ8ÒAÄ&A¿yA¹kÌA³Ò A®8sAšÇA£AklAÑÀA8AfAºAk
+Aw¢ÂAlojAa<AVžAJÕ`A?¢A4S¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|{pB|`
+ByFBvÆoBsùBq,ÃBn_ìBkBhÆ?BeùiBc,B`_ŒB]æBZÆBWù:BU,cBR_BO·BLÅàBIù	BG,3BD_]BAB>Å°B;øÚB9,B6_-B3WB0ÅB-øªB++ÔB(^ýB%'B"ÅPBøzB
++€B^ÍB÷BÅ BøJB+tB
+^B	ÇBÄñBøB+DAüŒÜA÷#/AñAëïÕAæV(AàŒ|AÛ"ÏAÕ"AÏïvAÊUÉAÄŒ
+A¿"pA¹ÃA³ïA®UiAš»ŒA£"AcAî¶AU
+A»]A!°AAwÜ¯Al©VAauþAVBŠAJóž¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|ìB|nBy¡ÁBvÔëBtBq;=BnngBk¡BhÔºBfäBc;B`n8B]¡bBZÔBXµBU:ßBRnBO¡1BLÔ[BJ
+BG:®BDmØBA¡B>Ô+B<UB9:B6mšB3 ÒB0ÓüB.%B+:OB(mxB% ¢B"ÓÌB õB
+:BmHB rBÓBÅB9ïB
+mB	 BBÓlBB9¿AüÙÒA÷@%AñŠxAì
+ÌAæsAàÙrAÛ?ÆAÕŠAÐ
+lAÊrÀAÄÙA¿?gA¹¥¹AŽ
+
+A®r`AšØ³A£?A¥ZA
+­Ar AØTA>§A€úAxAlãDAaV¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|gB|}By°<BvãeBtBqI¹Bn|âBk°
+Bhã6Bf`BcIB`|³B]¯ÝBZãBX0BUIYBR|BO¯­BLâÖBJ BGI*BD|SBA¯}B>â§B<ÐB9HúB6|$B3¯MB0âwB. B+HÊB({ôB%¯
+B"âGB pB
+HB{ÄB®íBâBABHjB
+{B	®ŸBáçBBH;AüöÈA÷]
+AñÃoAì)ÂAæAàöiAÛ\ŒAÕÃAÐ)cAÊ·AÄö	A¿\\A¹Â°AŽ)A®VAšõªA£[ýAÂPA(€A÷AõKA[AÁñAx4ô¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|ŠâB|ByŸ·BvñáBt%
+BqX4Bn^BkŸBhñ²Bf$ÛBcXB`/B]ŸXBZñBX$«BUWÕBRþBOŸ(BLñRBJ${BGW¥BDÏBAœøB>ñ"B<$LB9WuB6B3œÈB0ðòB.$
+B+WEB(oB%œB"ðÂB #ìB
+WB?BœiBðB#ŒBVæB
+B	œ9BðcB#BV¶Aý¿A÷zAñàfAìF¹Aæ­
+Aá`AÛy³AÕàAÐFYAÊ¬¬AÅ A¿ySA¹ßŠAŽEúA®¬MA© A£xôAßGAEA«îA@AjÉ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|µ]B|	ByÍ2Bw \Bt3Bqf°BnÚBkÍBi -Bf3WBcfB`©B]ÌÓBZÿýBX3&BUfPBRzBOÌ£BLÿÍBJ2÷BGf BDJBAÌtB>ÿB<2ÇB9eðB6B3ÌDB0ÿmB.2B+eÀB(êB%ÌB"ÿ=B 2gB
+eBºBËäBÿB27BeaB
+B	ËŽBþÞB2Be1Aý0¶A÷	Añý\Aìc°AæÊAá0WAÛ©AÕüüAÐcPAÊÉ£AÅ/öA¿JA¹üAŽbðA®ÉDA©/A£ëAü>AbA»¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|ÃØB|šByÛ®BwØBtBBqu+BnšUBkÛBišBfAÑBctûB`š%B]ÛNB[xBXA¢BUtËBR§õBOÛBMHBJArBGtBD§ÅBAÚïB?B<ABB9tlB6§B3Ú¿B1
+èB.AB+t<B(§eB%ÚB#
+¹B @âB
+t
+B§6BÚ_B
+B@³BsÜB
+§B	Ú0B
+YB@Bs¬AýM¬A÷Ž AòSAì§AææùAáMLAÛ³ AÖóAÐFAÊæAÅLíA¿³@AºAŽçA®æ;A©LA£²àA
+i¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|ÒTB|¶þByê(Bw
+QBtP{Bq¥Bn¶ÎBké÷Bi
+!BfPKBctB`¶B]éÈB[
+ñBXPBUEBR¶nBOéBM
+ÂBJOëBGBD¶>BAéhB?
+B<O»B9åB6¶B3é8B1
+bB.OB+µB(µßB%éB#
+2B O\B
+
+Bµ¯BèÙB
+BO,BVB
+µB	è©BÒBNüB&AýjA÷ÐóAò7EAìAçìAáj?AÛÐAÖ6æAÐ9AËAÅiàA¿Ð3Aº6AŽÚA¯,A©[µ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|àÐB|ÅyByø£Bw+ÍBt^öBqBnÅIBkøsBi+Bf^ÆBcðB`ÅB]øCB[+mBX^BUÀBRÄêBOøBM+=BJ^fBGBDÄºBA÷ãB?+
+B<^6B9`B6ÄB3÷³B1*ÝB.^B+0B(ÄZB%÷B#*­B ]×B
+BÄ*B÷TB*~B]§BÑB
+ÃúB	÷$B*NB]wB¡AýA÷íèAòT<AìºAç âAá6AÛíAÖSÜAÐº0AË AÅ×A¿í*AºS|AŽ¬¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|ïKB|ÓõBz
+Bw:GBtmqBq BnÓÄBlîBi:BfmABc kB`ÓB^ŸB[9èBXmBU ;BRÓeBPBM9žBJlâBG 
+BDÓ5BB^B?9B<l²B9ÛB6ÓB4/B19XB.lB+¬B(ÒÕB&ÿB#9)B lRB
+|BÒŠBÏB8ùBl"BLB
+ÒvB
+B8ÉBkóB
+Aý€Aø
+ßAòq2Aì×Aç=ÙAá€,AÜ
+AÖpÓAÐ×'AË=zAÅ£ÌA¿üU¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|ýÆB|âoBzBwHÃBt{ìBq¯Bnâ@BliBiHBf{œBc®æB`âB^:B[HcBX{BU®¶BRáàBP
+BMH3BJ{]BG®BDá°BBÚB?HB<{-B9®WB6áB4ªB1GÔB.zýB+®'B(áQB&zB#G€B zÎB
+­÷Bá!BJBGtBzB­ÇB
+àñB
+BGDBznB­AýÁAø'ÖAò)Aìô|AçZÐAáÁ#AÜ'wAÖÊAÐô
+AËL¥¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}
+AB|ðëBz$BwW>BthBqœBnð»Bl#åBiWBf8BcœbB`ðB^#µB[VÞBXBUœ2BRð[BP#
+BMV®BJØBGœBDð+BB#UB?VB<šB9ŒÒB6ïüB4#%B1VOB.yB+Œ¢B(ïÌB&"öB#VB IB
+ŒrBïB"ÆBUïBBŒCB
+ïlB
+"BUÀBéBŒAýÞyAøDÌAò« AísAçwÇAáÞAÜDlAÖõ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}ŒB|ÿfBz2Bwe¹BtãBqÌ
+Bnÿ6Bl2`BieBf³BcËÝB`ÿB^20B[eZBXBUË­BRþÖBP2 BMe*BJSBGË}BDþ§BB1ÐB?dúB<$B9ËMB6þwB41¡B1dÊB.ôB+Ë
+B(þGB&1qB#dB ÄB
+ÊîBþB1ABdkBBÊŸB
+ýèB
+1Bd;BeBÊAýûpAøaÃAòÈAí.jAçŒAáíE¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B})8B}
+áBzA
+Bwt5Bt§^BqÚBo
+²Bl@ÛBitBf§.BcÚXBa
+B^@«B[sÕBXŠþBUÚ(BS
+RBP@{BMs¥BJŠÏBGÙøBE
+"BB@LB?suB<ŠB9ÙÉB7
+òB4@
+B1sFB.ŠoB+ÙB)
+ÂB&?ìB#sB Š?B
+ÙiB
+B?ŒBræBŠBÙ9B
+
+cB
+?Br¶B¥ßBÙ
+AþgAø~ºAòå
+Aí=¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}7³B}
+]BzOBw°BtµÚBqéBo
+-BlOVBiBfµªBcèÓBaýB^O&B[PBXµzBUè£BSÍBPN÷BM BJµJBGètBEBBNÇB?ñB<µB9èDB7nB4NB1ÁB.ŽêB+èB)>B&NgB#B Ž»B
+çäBBN8BaBŽBçµB
+ÞB
+NB2BŽ[Bç
+Aþ5\Aøå¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}F.B}*ØBz^Bw+BtÄUBq÷~Bo*šBl]ÒBiûBfÄ%Bc÷NBa*xB^]¢B[ËBXÃõBU÷BS*HBP]rBMBJÃÅBGöïBE*BB]BB?lB<ÃB9ö¿B7)éB4]B1<B.ÃfB+öB))¹B&\ãB#
+B Ã6B
+ö`B)B\³BÝBÃBö/B
+)ZB
+\B­BÂ×Bï¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}TªB}9SBzl}BwŠBtÒÐBrúBo9#BllMBivBfÒ BdÊBa8óB^l
+B[GBXÒpBVBS8ÄBPkíBMBJÒABHjBE8BBkŸB?çB<ÒB::B78dB4kB1·B.ÑáB,
+B)84B&k^B#B Ñ±B
+ÛB8Bk.BWBÑB«B
+7ÕB
+jÿBC¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}c%B}GÌBzzöBw® BtáIBrsBoGBlzÆBi­ðBfáBdCBaGmB^zB[­ÀBXàêBVBSG=BPzgBM­BJàºBHäBEG
+BBz7B?­`B<àB:ŽB7FÝB4zB1­1B.àZB,B)F®B&y×B#­B à+B
+TBF}ByšB¬ÑBßûB%B
+?i¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}q B}VHBzqBwŒBtïÄBr"îBoVBlABiŒkBfïBd"ŸBaUèB^B[Œ;BXïeBV"BSUžBPâBMŒ
+BJï5BH"_BEUBB²B?»ÜB<ïB:"/B7UYB4B1»¬B.îÖB,!ÿB)U)B&SB#»|B î¥B
+!ÐBTùB#B»MBç¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}B}dÃBzìBwËBtþ@Br1iBodBlœBiÊæBfþBd1:BadcB^B[Ê·BXýàBV1
+BSd4BP]BMÊBJý°BH0ÚBEdBB-B?ÊWB<ýB:0ªB7cÔB4þB1Ê'B.ýQB,0{B)c€B&ÍB#ÉøB ý!B
+0KBcuB¹¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}B}s>BzŠhBwÙBu
+»Br?åBosBlŠ8BiÙbBg
+Bd?µBarßB^ŠB[Ù2BY
+\BV?
+BSr¯BP¥ØBMÙBK
+,BH?UBErBB¥©B?ØÒB=
+üB:?&B7rOB4¥yB1Ø£B/
+ÌB,>õB)r B&¥IB#ØsB!
+B
+7á¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}B}¹BzŽãBwè
+Bu6BrN`BoBlŽ³BiçÝBgBdN0BaZB^ŽB[ç­BY×BVN BS*BPŽTBMç}BK§BHMÑBEúBBŽ$B?çNB=wB:M¡B7ËB4³ôB1ç
+B/HB,MqB)B&³ÅB#à	¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}«B}5BzÃ^BwöBu)²Br\ÛBoBlÃ/BiöXBg)Bd\¬BaÕB^ÂÿB[ö(BY)RBV\|BS¥BPÂÏBMõùBK)"BH\LBEvBBÂB?õÉB=(óB:\
+B7EB4ÂpB1õB/(ÃB,[íB)1¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}ºB}°BzÑÚBxBu8-BrkWBoBlÑªBjÔBg7ýBdk'BaPB^ÑzB\€BY7ÍBVj÷BS!BPÑJBNtBK7BHjÇBEñBBÑB@DB=7mB:jB7ÁB4ÐëB2B/0Y¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}ÈB}­+BzàUBxBuFšBryÒBo¬üBlà%BjOBgFxBdy¢Ba¬ÌB^ßõB\BYFIBVyrBS¬BPßÆBNïBKFBHyCBE¬lBBßB@ÀB=EéB:yB7¬=B4Ø¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}ÖÿB}»§BzîÐBx!úBuU$BrMBo»wBlî Bj!ÊBgTôBd
+Ba»GB^îqB\!BYTÄBVîBS»BPîABN!kBKTBHœBEºèBBîB@!;B=TeB:©¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}åzB}Ê"BzýLBx0uBucBrÈBoÉòBlý
+Bj0EBgcoBdBaÉÂB^üìB\0BYc?BViBSÉBPüŒBN/åBKcBH9BEÉcBBüB@(Ñ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}óöB}ØB{
+ÅBx>îBurBr¥BBoØkBm
+Bj>¿BgqèBd¥BaØ<B_
+eB\>BYq¹BV€âBSØ
+BQ
+6BN>_BKqBH€³BEÐ÷¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~qB}çB{@BxMjBuBr³œBoæçBmBjM:BgdBd³Baæ·B_áB\M
+BY3BV³^BSæBQ±BNLÛBKy¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~ìB}õB{(»Bx[åBuBrÂ8BoõbBm(Bj[µBgßBdÂ	Baõ2B_([B\[BY¯BVÁÙBSõBQ!G¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~gB~
+B{77Bxj`BuBrÐŽBpÝBm7Bjj1BgZBdÐBb®B_6×B\jBY+BVÉo¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~-ãB~B{E²BxxÜBu¬Brß/BpYBmEBjx«Bg«ÖBdÞÿBb)B_ESB\q¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~<^B~!B{T-BxWBuºBríªBp ÓBmSþBj'BgºQBdí{Bb¿¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~JÙB~/B{b©BxÒBuÈûBrü&Bp/OBmbyBj£BgÁç¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~YUB~=úB{q#Bx€MBu×wBs
+¡Bp=ËBmj¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~gÏB~LuB{Bx²ÉBuåóBs7¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~vKB~ZñB{Bxº_¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~ÇB~b
+¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                  -32 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   64 / length of data axis 1                          NAXIS2  =                   64 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             B|  Bx  Bt  Bp  Bl  Bh  Bd  B`  B\  BX  BT  BP  BL  BH  BD  B@  B<  B8  B4  B0  B,  B(  B$  B   B
+  B  B  B  B
+  B  B  B   Aø  Að  Aè  Aà  AØ  AÐ  AÈ  AÀ  Až  A°  Aš  A   A  A  A  A  Ap  A`  AP  A@  A0  A   A  A   @à  @À  @   @  @@  @   ?      B|
+=Bx
+=Bt
+=Bp
+=Bl
+=Bh
+=Bd
+=B`
+=B\
+=BX
+=BT
+=BP
+=BL
+=BH
+=BD
+=B@
+=B<
+=B8
+=B4
+=B0
+=B,
+=B(
+=B$
+=B 
+=B
+
+=B
+=B
+=B
+=B
+
+=B
+=B
+=B 
+=Aø{Að{Aè{Aà{AØ{AÐ{AÈ{AÀ{Až{A°{Aš{A {A{A{A{A{Ap(öA`(öAP(öA@(öA0(öA (öA(öA (ö@àQì@ÀQì@ Qì@Qì@@£×@ £×?G®<#×
+B|{Bx{Bt{Bp{Bl{Bh{Bd{B`{B\{BX{BT{BP{BL{BH{BD{B@{B<{B8{B4{B0{B,{B({B${B {B
+{B{B{B{B
+{B{B{B {Aø(öAð(öAè(öAà(öAØ(öAÐ(öAÈ(öAÀ(öAž(öA°(öAš(öA (öA(öA(öA(öA(öApQìA`QìAPQìA@QìA0QìA QìAQìA Qì@à£×@À£×@ £×@£×@AG®@G®?\<£×
+B|
+žBx
+žBt
+žBp
+žBl
+žBh
+žBd
+žB`
+žB\
+žBX
+žBT
+žBP
+žBL
+žBH
+žBD
+žB@
+žB<
+žB8
+žB4
+žB0
+žB,
+žB(
+žB$
+žB 
+žB
+
+žB
+žB
+žB
+žB
+
+žB
+žB
+žB 
+žAø=qAð=qAè=qAà=qAØ=qAÐ=qAÈ=qAÀ=qAž=qA°=qAš=qA =qA=qA=qA=qA=qApzáA`záAPzáA@záA0záA záAzáA zá@àõÃ@ÀõÃ@ õÃ@õÃ@Aë
+@ë
+?×
+<õÂB|(öBx(öBt(öBp(öBl(öBh(öBd(öB`(öB\(öBX(öBT(öBP(öBL(öBH(öBD(öB@(öB<(öB8(öB4(öB0(öB,(öB((öB$(öB (öB
+(öB(öB(öB(öB
+(öB(öB(öB (öAøQìAðQìAèQìAàQìAØQìAÐQìAÈQìAÀQìAžQìA°QìAšQìA QìAQìAQìAQìAQìAp£×A`£×AP£×A@£×A0£×A £×A£×A £×@áG®@ÁG®@¡G®@G®@B\@\?
+
+ž=#×
+B|33Bx33Bt33Bp33Bl33Bh33Bd33B`33B\33BX33BT33BP33BL33BH33BD33B@33B<33B833B433B033B,33B(33B$33B 33B
+33B33B33B33B
+33B33B33B 33AøffAðffAèffAàffAØffAÐffAÈffAÀffAžffA°ffAšffA ffAffAffAffAffApÌÍA`ÌÍAPÌÍA@ÌÍA0ÌÍA ÌÍAÌÍA ÌÍ@á@Á@¡@@C33@33?ff=LÌÍB|=qBx=qBt=qBp=qBl=qBh=qBd=qB`=qB\=qBX=qBT=qBP=qBL=qBH=qBD=qB@=qB<=qB8=qB4=qB0=qB,=qB(=qB$=qB =qB
+=qB=qB=qB=qB
+=qB=qB=qB =qAøzáAðzáAèzáAàzáAØzáAÐzáAÈzáAÀzáAžzáA°záAšzáA záAzáAzáAzáAzáApõÃA`õÃAPõÃA@õÃA0õÃA õÃAõÃA õÃ@áë
+@Áë
+@¡ë
+@ë
+@C×
+@×
+?®=uÂB|G®BxG®BtG®BpG®BlG®BhG®BdG®B`G®B\G®BXG®BTG®BPG®BLG®BHG®BDG®B@G®B<G®B8G®B4G®B0G®B,G®B(G®B$G®B G®B
+G®BG®BG®BG®B
+G®BG®BG®B G®Aø\Að\Aè\Aà\AØ\AÐ\AÈ\AÀ\Až\A°\Aš\A \A\A\A\A\Aq
+žAa
+žAQ
+žAA
+žA1
+žA!
+žA
+žA
+ž@â=q@Â=q@¢=q@=q@Dzá@zá?õÃ=\)B|QìBxQìBtQìBpQìBlQìBhQìBdQìB`QìB\QìBXQìBTQìBPQìBLQìBHQìBDQìB@QìB<QìB8QìB4QìB0QìB,QìB(QìB$QìB QìB
+QìBQìBQìBQìB
+QìBQìBQìB QìAø£×Að£×Aè£×Aà£×AØ£×AÐ£×AÈ£×AÀ£×Až£×A°£×Aš£×A £×A£×A£×A£×A£×AqG®AaG®AQG®AAG®A1G®A!G®AG®AG®@â\@Â\@¢\@\@E
+ž@
+ž?=q=£×
+B|\)Bx\)Bt\)Bp\)Bl\)Bh\)Bd\)B`\)B\\)BX\)BT\)BP\)BL\)BH\)BD\)B@\)B<\)B8\)B4\)B0\)B,\)B(\)B$\)B \)B
+\)B\)B\)B\)B
+\)B\)B\)B \)AøžRAðžRAèžRAàžRAØžRAÐžRAÈžRAÀžRAžžRA°žRAšžRA žRAžRAžRAžRAžRAqp€Aap€AQp€AAp€A1p€A!p€Ap€Ap€@âáH@ÂáH@¢áH@áH@EÂ@Â?
+=žQìB|ffBxffBtffBpffBlffBhffBdffB`ffB\ffBXffBTffBPffBLffBHffBDffB@ffB<ffB8ffB4ffB0ffB,ffB(ffB$ffB ffB
+ffBffBffBffB
+ffBffBffB ffAøÌÍAðÌÍAèÌÍAàÌÍAØÌÍAÐÌÍAÈÌÍAÀÌÍAžÌÍA°ÌÍAšÌÍA ÌÍAÌÍAÌÍAÌÍAÌÍAqAaAQAAA1A!AA@ã33@Ã33@£33@33@Fff@ff?ÌÍ=ÌÌÍB|p€Bxp€Btp€Bpp€Blp€Bhp€Bdp€B`p€B\p€BXp€BTp€BPp€BLp€BHp€BDp€B@p€B<p€B8p€B4p€B0p€B,p€B(p€B$p€B p€B
+p€Bp€Bp€Bp€B
+p€Bp€Bp€B p€AøáHAðáHAèáHAàáHAØáHAÐáHAÈáHAÀáHAžáHA°áHAšáHA áHAáHAáHAáHAáHAqÂAaÂAQÂAAÂA1ÂA!ÂAÂAÂ@ã
+@Ã
+@£
+@
+@G
+=@
+=?{=áG®B|záBxzáBtzáBpzáBlzáBhzáBdzáB`záB\záBXzáBTzáBPzáBLzáBHzáBDzáB@záB<záB8záB4záB0záB,záB(záB$záB záB
+záBzáBzáBzáB
+záBzáBzáB záAøõÃAðõÃAèõÃAàõÃAØõÃAÐõÃAÈõÃAÀõÃAžõÃA°õÃAšõÃA õÃAõÃAõÃAõÃAõÃAqë
+Aaë
+AQë
+AAë
+A1ë
+A!ë
+Aë
+Aë
+@ã×
+@Ã×
+@£×
+@×
+@G®@®?\)=õÂB|
+Bx
+Bt
+Bp
+Bl
+Bh
+Bd
+B`
+B\
+BX
+BT
+BP
+BL
+BH
+BD
+B@
+B<
+B8
+B4
+B0
+B,
+B(
+B$
+B 
+B
+
+B
+B
+B
+B
+
+B
+B
+B 
+Aù
+=Añ
+=Aé
+=Aá
+=AÙ
+=AÑ
+=AÉ
+=AÁ
+=A¹
+=A±
+=A©
+=A¡
+=A
+=A
+=A
+=A
+=Ar{Ab{AR{AB{A2{A"{A{A{@ä(ö@Ä(ö@€(ö@(ö@HQì@Qì?£×>
+žB|\Bx\Bt\Bp\Bl\Bh\Bd\B`\B\\BX\BT\BP\BL\BH\BD\B@\B<\B8\B4\B0\B,\B(\B$\B \B
+\B\B\B\B
+\B\B\B \Aù
+žAñ
+žAé
+žAá
+žAÙ
+žAÑ
+žAÉ
+žAÁ
+žA¹
+žA±
+žA©
+žA¡
+žA
+žA
+žA
+žA
+žAr=qAb=qAR=qAB=qA2=qA"=qA=qA=q@äzá@Äzá@€zá@zá@HõÃ@õÃ?ë
+>\)B|BxBtBpBlBhBdB`B\BXBTBPBLBHBDB@B<B8B4B0B,B(B$B B
+BBBB
+BBB Aù33Añ33Aé33Aá33AÙ33AÑ33AÉ33AÁ33A¹33A±33A©33A¡33A33A33A33A33ArffAbffARffABffA2ffA"ffAffAff@äÌÍ@ÄÌÍ@€ÌÍ@ÌÍ@I@	?33>B|£×Bx£×Bt£×Bp£×Bl£×Bh£×Bd£×B`£×B\£×BX£×BT£×BP£×BL£×BH£×BD£×B@£×B<£×B8£×B4£×B0£×B,£×B(£×B$£×B £×B
+£×B£×B£×B£×B
+£×B£×B£×B £×AùG®AñG®AéG®AáG®AÙG®AÑG®AÉG®AÁG®A¹G®A±G®A©G®A¡G®AG®AG®AG®AG®Ar\Ab\AR\AB\A2\A"\A\A\@å
+ž@Å
+ž@¥
+ž@
+
+ž@J=q@
+=q?zá>#×
+B|®Bx®Bt®Bp®Bl®Bh®Bd®B`®B\®BX®BT®BP®BL®BH®BD®B@®B<®B8®B4®B0®B,®B(®B$®B ®B
+®B®B®B®B
+®B®B®B ®Aù\)Añ\)Aé\)Aá\)AÙ\)AÑ\)AÉ\)AÁ\)A¹\)A±\)A©\)A¡\)A\)A\)A\)A\)AržRAbžRARžRABžRA2žRA"žRAžRAžR@åp€@Åp€@¥p€@
+p€@JáH@
+áH?Â>.{B|žRBxžRBtžRBpžRBlžRBhžRBdžRB`žRB\žRBXžRBTžRBPžRBLžRBHžRBDžRB@žRB<žRB8žRB4žRB0žRB,žRB(žRB$žRB žRB
+žRBžRBžRBžRB
+žRBžRBžRB žRAùp€Añp€Aép€Aáp€AÙp€AÑp€AÉp€AÁp€A¹p€A±p€A©p€A¡p€Ap€Ap€Ap€Ap€AráHAbáHARáHABáHA2áHA"áHAáHAáH@åÂ@ÅÂ@¥Â@
+Â@K
+@
+
+?
+>>8QìB|ÂBxÂBtÂBpÂBlÂBhÂBdÂB`ÂB\ÂBXÂBTÂBPÂBLÂBHÂBDÂB@ÂB<ÂB8ÂB4ÂB0ÂB,ÂB(ÂB$ÂB ÂB
+ÂBÂBÂBÂB
+ÂBÂBÂB ÂAù
+Añ
+Aé
+Aá
+AÙ
+AÑ
+AÉ
+AÁ
+A¹
+A±
+A©
+A¡
+A
+A
+A
+A
+As
+=Ac
+=AS
+=AC
+=A3
+=A#
+=A
+=A
+=@æ{@Æ{@Š{@{@L(ö@
+(ö?Qì>B\B|ÌÍBxÌÍBtÌÍBpÌÍBlÌÍBhÌÍBdÌÍB`ÌÍB\ÌÍBXÌÍBTÌÍBPÌÍBLÌÍBHÌÍBDÌÍB@ÌÍB<ÌÍB8ÌÍB4ÌÍB0ÌÍB,ÌÍB(ÌÍB$ÌÍB ÌÍB
+ÌÍBÌÍBÌÍBÌÍB
+ÌÍBÌÍBÌÍB ÌÍAùAñAéAáAÙAÑAÉAÁA¹A±A©A¡AAAAAs33Ac33AS33AC33A333A#33A33A33@æff@Æff@Šff@ff@LÌÍ@
+ÌÍ?>LÌÍB|×
+Bx×
+Bt×
+Bp×
+Bl×
+Bh×
+Bd×
+B`×
+B\×
+BX×
+BT×
+BP×
+BL×
+BH×
+BD×
+B@×
+B<×
+B8×
+B4×
+B0×
+B,×
+B(×
+B$×
+B ×
+B
+×
+B×
+B×
+B×
+B
+×
+B×
+B×
+B ×
+Aù®Añ®Aé®Aá®AÙ®AÑ®AÉ®AÁ®A¹®A±®A©®A¡®A®A®A®A®As\)Ac\)AS\)AC\)A3\)A#\)A\)A\)@æžR@ÆžR@ŠžR@žR@Mp€@
+p€?áH>W
+=B|áHBxáHBtáHBpáHBláHBháHBdáHB`áHB\áHBXáHBTáHBPáHBLáHBHáHBDáHB@áHB<áHB8áHB4áHB0áHB,áHB(áHB$áHB áHB
+áHBáHBáHBáHB
+áHBáHBáHB áHAùÂAñÂAéÂAáÂAÙÂAÑÂAÉÂAÁÂA¹ÂA±ÂA©ÂA¡ÂAÂAÂAÂAÂAs
+Ac
+AS
+AC
+A3
+A#
+A
+A
+@ç
+=@Ç
+=@§
+=@
+=@N{@{?(ö>aG®B|ë
+Bxë
+Btë
+Bpë
+Blë
+Bhë
+Bdë
+B`ë
+B\ë
+BXë
+BTë
+BPë
+BLë
+BHë
+BDë
+B@ë
+B<ë
+B8ë
+B4ë
+B0ë
+B,ë
+B(ë
+B$ë
+B ë
+B
+ë
+Bë
+Bë
+Bë
+B
+ë
+Bë
+Bë
+B ë
+Aù×
+Añ×
+Aé×
+Aá×
+AÙ×
+AÑ×
+AÉ×
+AÁ×
+A¹×
+A±×
+A©×
+A¡×
+A×
+A×
+A×
+A×
+As®Ac®AS®AC®A3®A#®A®A®@ç\)@Ç\)@§\)@\)@NžR@žR?p€>k
+B|õÃBxõÃBtõÃBpõÃBlõÃBhõÃBdõÃB`õÃB\õÃBXõÃBTõÃBPõÃBLõÃBHõÃBDõÃB@õÃB<õÃB8õÃB4õÃB0õÃB,õÃB(õÃB$õÃB õÃB
+õÃBõÃBõÃBõÃB
+õÃBõÃBõÃB õÃAùë
+Añë
+Aéë
+Aáë
+AÙë
+AÑë
+AÉë
+AÁë
+A¹ë
+A±ë
+A©ë
+A¡ë
+Aë
+Aë
+Aë
+Aë
+As×
+Ac×
+AS×
+AC×
+A3×
+A#×
+A×
+A×
+@ç®@Ç®@§®@®@O\)@\)?žR>uÂB}  By  Bu  Bq  Bm  Bi  Be  Ba  B]  BY  BU  BQ  BM  BI  BE  BA  B=  B9  B5  B1  B-  B)  B%  B!  B
+  B  B  B  B
+  B	  B  B  Aú  Aò  Aê  Aâ  AÚ  AÒ  AÊ  AÂ  Aº  A²  Aª  A¢  A  A  A  A  At  Ad  AT  AD  A4  A$  A  A  @è  @È  @š  @  @P  @  ?   >  B}
+=By
+=Bu
+=Bq
+=Bm
+=Bi
+=Be
+=Ba
+=B]
+=BY
+=BU
+=BQ
+=BM
+=BI
+=BE
+=BA
+=B=
+=B9
+=B5
+=B1
+=B-
+=B)
+=B%
+=B!
+=B
+
+=B
+=B
+=B
+=B
+=B	
+=B
+=B
+=Aú{Aò{Aê{Aâ{AÚ{AÒ{AÊ{AÂ{Aº{A²{Aª{A¢{A{A{A{A{At(öAd(öAT(öAD(öA4(öA$(öA(öA(ö@èQì@ÈQì@šQì@Qì@P£×@£×?¡G®>
+
+žB}{By{Bu{Bq{Bm{Bi{Be{Ba{B]{BY{BU{BQ{BM{BI{BE{BA{B={B9{B5{B1{B-{B){B%{B!{B
+{B{B{B{B
+{B	{B{B{Aú(öAò(öAê(öAâ(öAÚ(öAÒ(öAÊ(öAÂ(öAº(öA²(öAª(öA¢(öA(öA(öA(öA(öAtQìAdQìATQìADQìA4QìA$QìAQìAQì@è£×@È£×@š£×@£×@QG®@G®?¢\>=qB}
+žBy
+žBu
+žBq
+žBm
+žBi
+žBe
+žBa
+žB]
+žBY
+žBU
+žBQ
+žBM
+žBI
+žBE
+žBA
+žB=
+žB9
+žB5
+žB1
+žB-
+žB)
+žB%
+žB!
+žB
+
+žB
+žB
+žB
+žB
+
+žB	
+žB
+žB
+žAú=qAò=qAê=qAâ=qAÚ=qAÒ=qAÊ=qAÂ=qAº=qA²=qAª=qA¢=qA=qA=qA=qA=qAtzáAdzáATzáADzáA4záA$záAzáAzá@èõÃ@ÈõÃ@šõÃ@õÃ@Që
+@ë
+?£×
+>\)B}(öBy(öBu(öBq(öBm(öBi(öBe(öBa(öB](öBY(öBU(öBQ(öBM(öBI(öBE(öBA(öB=(öB9(öB5(öB1(öB-(öB)(öB%(öB!(öB
+(öB(öB(öB(öB
+(öB	(öB(öB(öAúQìAòQìAêQìAâQìAÚQìAÒQìAÊQìAÂQìAºQìA²QìAªQìA¢QìAQìAQìAQìAQìAt£×Ad£×AT£×AD£×A4£×A$£×A£×A£×@éG®@ÉG®@©G®@G®@R\@\?¥
+ž>záB}33By33Bu33Bq33Bm33Bi33Be33Ba33B]33BY33BU33BQ33BM33BI33BE33BA33B=33B933B533B133B-33B)33B%33B!33B
+33B33B33B33B
+33B	33B33B33AúffAòffAêffAâffAÚffAÒffAÊffAÂffAºffA²ffAªffA¢ffAffAffAffAffAtÌÍAdÌÍATÌÍADÌÍA4ÌÍA$ÌÍAÌÍAÌÍ@é@É@©@@S33@33?Šff>B}=qBy=qBu=qBq=qBm=qBi=qBe=qBa=qB]=qBY=qBU=qBQ=qBM=qBI=qBE=qBA=qB==qB9=qB5=qB1=qB-=qB)=qB%=qB!=qB
+=qB=qB=qB=qB
+=qB	=qB=qB=qAúzáAòzáAêzáAâzáAÚzáAÒzáAÊzáAÂzáAºzáA²záAªzáA¢záAzáAzáAzáAzáAtõÃAdõÃATõÃADõÃA4õÃA$õÃAõÃAõÃ@éë
+@Éë
+@©ë
+@ë
+@S×
+@×
+?§®>žRB}G®ByG®BuG®BqG®BmG®BiG®BeG®BaG®B]G®BYG®BUG®BQG®BMG®BIG®BEG®BAG®B=G®B9G®B5G®B1G®B-G®B)G®B%G®B!G®B
+G®BG®BG®BG®B
+G®B	G®BG®BG®Aú\Aò\Aê\Aâ\AÚ\AÒ\AÊ\AÂ\Aº\A²\Aª\A¢\A\A\A\A\Au
+žAe
+žAU
+žAE
+žA5
+žA%
+žA
+žA
+ž@ê=q@Ê=q@ª=q@=q@Tzá@zá?šõÂ>£×
+B}QìByQìBuQìBqQìBmQìBiQìBeQìBaQìB]QìBYQìBUQìBQQìBMQìBIQìBEQìBAQìB=QìB9QìB5QìB1QìB-QìB)QìB%QìB!QìB
+QìBQìBQìBQìB
+QìB	QìBQìBQìAú£×Aò£×Aê£×Aâ£×AÚ£×AÒ£×AÊ£×AÂ£×Aº£×A²£×Aª£×A¢£×A£×A£×A£×A£×AuG®AeG®AUG®AEG®A5G®A%G®AG®AG®@ê\@Ê\@ª\@\@U
+ž@
+ž?ª=q>šõÃB}\)By\)Bu\)Bq\)Bm\)Bi\)Be\)Ba\)B]\)BY\)BU\)BQ\)BM\)BI\)BE\)BA\)B=\)B9\)B5\)B1\)B-\)B)\)B%\)B!\)B
+\)B\)B\)B\)B
+\)B	\)B\)B\)AúžRAòžRAêžRAâžRAÚžRAÒžRAÊžRAÂžRAºžRA²žRAªžRA¢žRAžRAžRAžRAžRAup€Aep€AUp€AEp€A5p€A%p€Ap€Ap€@êáH@ÊáH@ªáH@áH@UÂ@Â?«
+>®{B}ffByffBuffBqffBmffBiffBeffBaffB]ffBYffBUffBQffBMffBIffBEffBAffB=ffB9ffB5ffB1ffB-ffB)ffB%ffB!ffB
+ffBffBffBffB
+ffB	ffBffBffAúÌÍAòÌÍAêÌÍAâÌÍAÚÌÍAÒÌÍAÊÌÍAÂÌÍAºÌÍA²ÌÍAªÌÍA¢ÌÍAÌÍAÌÍAÌÍAÌÍAuAeAUAEA5A%AA@ë33@Ë33@«33@33@Vff@ff?¬ÌÍ>³33B}p€Byp€Bup€Bqp€Bmp€Bip€Bep€Bap€B]p€BYp€BUp€BQp€BMp€BIp€BEp€BAp€B=p€B9p€B5p€B1p€B-p€B)p€B%p€B!p€B
+p€Bp€Bp€Bp€B
+p€B	p€Bp€Bp€AúáHAòáHAêáHAâáHAÚáHAÒáHAÊáHAÂáHAºáHA²áHAªáHA¢áHAáHAáHAáHAáHAuÂAeÂAUÂAEÂA5ÂA%ÂAÂAÂ@ë
+@Ë
+@«
+@
+@W
+>@
+>?®{>žQìB}záByzáBuzáBqzáBmzáBizáBezáBazáB]záBYzáBUzáBQzáBMzáBIzáBEzáBAzáB=záB9záB5záB1záB-záB)záB%záB!záB
+záBzáBzáBzáB
+záB	záBzáBzáAúõÃAòõÃAêõÃAâõÃAÚõÃAÒõÃAÊõÃAÂõÃAºõÃA²õÃAªõÃA¢õÃAõÃAõÃAõÃAõÃAuë
+Aeë
+AUë
+AEë
+A5ë
+A%ë
+Aë
+Aë
+@ë×
+@Ë×
+@«×
+@×
+@W®@®?¯\)>œp€B}
+By
+Bu
+Bq
+Bm
+Bi
+Be
+Ba
+B]
+BY
+BU
+BQ
+BM
+BI
+BE
+BA
+B=
+B9
+B5
+B1
+B-
+B)
+B%
+B!
+B
+
+B
+B
+B
+B
+
+B	
+B
+B
+Aû
+=Aó
+=Aë
+=Aã
+=AÛ
+=AÓ
+=AË
+=AÃ
+=A»
+=A³
+=A«
+=A£
+=A
+=A
+=A
+=A
+=Av{Af{AV{AF{A6{A&{A{A{@ì(ö@Ì(ö@¬(ö@(ö@XQì@Qì?°£×>Â\B}\By\Bu\Bq\Bm\Bi\Be\Ba\B]\BY\BU\BQ\BM\BI\BE\BA\B=\B9\B5\B1\B-\B)\B%\B!\B
+\B\B\B\B
+\B	\B\B\Aû
+žAó
+žAë
+žAã
+žAÛ
+žAÓ
+žAË
+žAÃ
+žA»
+žA³
+žA«
+žA£
+žA
+žA
+žA
+žA
+žAv=qAf=qAV=qAF=qA6=qA&=qA=qA=q@ìzá@Ìzá@¬zá@zá@XõÂ@õÂ?±ë
+>Ç®B}ByBuBqBmBiBeBaB]BYBUBQBMBIBEBAB=B9B5B1B-B)B%B!B
+BBBB
+B	BBAû33Aó33Aë33Aã33AÛ33AÓ33AË33AÃ33A»33A³33A«33A£33A33A33A33A33AvffAfffAVffAFffA6ffA&ffAffAff@ìÌÍ@ÌÌÍ@¬ÌÍ@ÌÍ@Y@?³33>ÌÌÍB}£×By£×Bu£×Bq£×Bm£×Bi£×Be£×Ba£×B]£×BY£×BU£×BQ£×BM£×BI£×BE£×BA£×B=£×B9£×B5£×B1£×B-£×B)£×B%£×B!£×B
+£×B£×B£×B£×B
+£×B	£×B£×B£×AûG®AóG®AëG®AãG®AÛG®AÓG®AËG®AÃG®A»G®A³G®A«G®A£G®AG®AG®AG®AG®Av\Af\AV\AF\A6\A&\A\A\@í
+ž@Í
+ž@­
+ž@
+ž@Z=q@=q?Žzá>Ñë
+B}®By®Bu®Bq®Bm®Bi®Be®Ba®B]®BY®BU®BQ®BM®BI®BE®BA®B=®B9®B5®B1®B-®B)®B%®B!®B
+®B®B®B®B
+®B	®B®B®Aû\)Aó\)Aë\)Aã\)AÛ\)AÓ\)AË\)AÃ\)A»\)A³\)A«\)A£\)A\)A\)A\)A\)AvžRAfžRAVžRAFžRA6žRA&žRAžRAžR@íp€@Íp€@­p€@p€@ZáH@áH?µÂ>×
+=B}žRByžRBužRBqžRBmžRBižRBežRBažRB]žRBYžRBUžRBQžRBMžRBIžRBEžRBAžRB=žRB9žRB5žRB1žRB-žRB)žRB%žRB!žRB
+žRBžRBžRBžRB
+žRB	žRBžRBžRAûp€Aóp€Aëp€Aãp€AÛp€AÓp€AËp€AÃp€A»p€A³p€A«p€A£p€Ap€Ap€Ap€Ap€AváHAfáHAVáHAFáHA6áHA&áHAáHAáH@íÂ@ÍÂ@­Â@Â@[
+@
+?·
+>>Ü(öB}ÂByÂBuÂBqÂBmÂBiÂBeÂBaÂB]ÂBYÂBUÂBQÂBMÂBIÂBEÂBAÂB=ÂB9ÂB5ÂB1ÂB-ÂB)ÂB%ÂB!ÂB
+ÂBÂBÂBÂB
+ÂB	ÂBÂBÂAû
+Aó
+Aë
+Aã
+AÛ
+AÓ
+AË
+AÃ
+A»
+A³
+A«
+A£
+A
+A
+A
+A
+Aw
+=Ag
+=AW
+=AG
+=A7
+=A'
+=A
+=A
+=@î{@Î{@®{@{@\(ö@
+(ö?žQì>áG®B}ÌÍByÌÍBuÌÍBqÌÍBmÌÍBiÌÍBeÌÍBaÌÍB]ÌÍBYÌÍBUÌÍBQÌÍBMÌÍBIÌÍBEÌÍBAÌÍB=ÌÍB9ÌÍB5ÌÍB1ÌÍB-ÌÍB)ÌÍB%ÌÍB!ÌÍB
+ÌÍBÌÍBÌÍBÌÍB
+ÌÍB	ÌÍBÌÍBÌÍAûAóAëAãAÛAÓAËAÃA»A³A«A£AAAAAw33Ag33AW33AG33A733A'33A33A33@îff@Îff@®ff@ff@\ÌÍ@
+ÌÍ?¹>æffB}×
+By×
+Bu×
+Bq×
+Bm×
+Bi×
+Be×
+Ba×
+B]×
+BY×
+BU×
+BQ×
+BM×
+BI×
+BE×
+BA×
+B=×
+B9×
+B5×
+B1×
+B-×
+B)×
+B%×
+B!×
+B
+×
+B×
+B×
+B×
+B
+×
+B	×
+B×
+B×
+Aû®Aó®Aë®Aã®AÛ®AÓ®AË®AÃ®A»®A³®A«®A£®A®A®A®A®Aw\)Ag\)AW\)AG\)A7\)A'\)A\)A\)@îžR@ÎžR@®žR@žR@]p€@
+p€?ºáH>ë
+B}áHByáHBuáHBqáHBmáHBiáHBeáHBaáHB]áHBYáHBUáHBQáHBMáHBIáHBEáHBAáHB=áHB9áHB5áHB1áHB-áHB)áHB%áHB!áHB
+áHBáHBáHBáHB
+áHB	áHBáHBáHAûÂAóÂAëÂAãÂAÛÂAÓÂAËÂAÃÂA»ÂA³ÂA«ÂA£ÂAÂAÂAÂAÂAw
+Ag
+AW
+AG
+A7
+A'
+A
+A
+@ï
+=@Ï
+=@¯
+=@
+=@^{@
+{?Œ(ö>ð£×B}ë
+Byë
+Buë
+Bqë
+Bmë
+Bië
+Beë
+Baë
+B]ë
+BYë
+BUë
+BQë
+BMë
+BIë
+BEë
+BAë
+B=ë
+B9ë
+B5ë
+B1ë
+B-ë
+B)ë
+B%ë
+B!ë
+B
+ë
+Bë
+Bë
+Bë
+B
+ë
+B	ë
+Bë
+Bë
+Aû×
+Aó×
+Aë×
+Aã×
+AÛ×
+AÓ×
+AË×
+AÃ×
+A»×
+A³×
+A«×
+A£×
+A×
+A×
+A×
+A×
+Aw®Ag®AW®AG®A7®A'®A®A®@ï\)@Ï\)@¯\)@\)@^žR@
+žR?œp€>õÂB}õÃByõÃBuõÃBqõÃBmõÃBiõÃBeõÃBaõÃB]õÃBYõÃBUõÃBQõÃBMõÃBIõÃBEõÃBAõÃB=õÃB9õÃB5õÃB1õÃB-õÃB)õÃB%õÃB!õÃB
+õÃBõÃBõÃBõÃB
+õÃB	õÃBõÃBõÃAûë
+Aóë
+Aëë
+Aãë
+AÛë
+AÓë
+AËë
+AÃë
+A»ë
+A³ë
+A«ë
+A£ë
+Aë
+Aë
+Aë
+Aë
+Aw×
+Ag×
+AW×
+AG×
+A7×
+A'×
+A×
+A×
+@ï®@Ï®@¯®@®@_\)@\)?ŸžR>úáHB~  Bz  Bv  Br  Bn  Bj  Bf  Bb  B^  BZ  BV  BR  BN  BJ  BF  BB  B>  B:  B6  B2  B.  B*  B&  B"  B
+  B  B  B  B  B
+  B  B  Aü  Aô  Aì  Aä  AÜ  AÔ  AÌ  AÄ  AŒ  AŽ  A¬  A€  A  A  A  A  Ax  Ah  AX  AH  A8  A(  A  A  @ð  @Ð  @°  @  @`  @   ?À  ?   B~
+=Bz
+=Bv
+=Br
+=Bn
+=Bj
+=Bf
+=Bb
+=B^
+=BZ
+=BV
+=BR
+=BN
+=BJ
+=BF
+=BB
+=B>
+=B:
+=B6
+=B2
+=B.
+=B*
+=B&
+=B"
+=B
+
+=B
+=B
+=B
+=B
+=B
+
+=B
+=B
+=Aü{Aô{Aì{Aä{AÜ{AÔ{AÌ{AÄ{AŒ{AŽ{A¬{A€{A{A{A{A{Ax(öAh(öAX(öAH(öA8(öA((öA(öA(ö@ðQì@ÐQì@°Qì@Qì@`£×@ £×?ÁG®?\B~{Bz{Bv{Br{Bn{Bj{Bf{Bb{B^{BZ{BV{BR{BN{BJ{BF{BB{B>{B:{B6{B2{B.{B*{B&{B"{B
+{B{B{B{B{B
+{B{B{Aü(öAô(öAì(öAä(öAÜ(öAÔ(öAÌ(öAÄ(öAŒ(öAŽ(öA¬(öA€(öA(öA(öA(öA(öAxQìAhQìAXQìAHQìA8QìA(QìAQìAQì@ð£×@Ð£×@°£×@£×@aG®@!G®?Â\?
+žB~
+žBz
+žBv
+žBr
+žBn
+žBj
+žBf
+žBb
+žB^
+žBZ
+žBV
+žBR
+žBN
+žBJ
+žBF
+žBB
+žB>
+žB:
+žB6
+žB2
+žB.
+žB*
+žB&
+žB"
+žB
+
+žB
+žB
+žB
+žB
+žB
+
+žB
+žB
+žAü=qAô=qAì=qAä=qAÜ=qAÔ=qAÌ=qAÄ=qAŒ=qAŽ=qA¬=qA€=qA=qA=qA=qA=qAxzáAhzáAXzáAHzáA8záA(záAzáAzá@ðõÂ@ÐõÂ@°õÂ@õÂ@aë
+@!ë
+?Ã×
+?®B~(öBz(öBv(öBr(öBn(öBj(öBf(öBb(öB^(öBZ(öBV(öBR(öBN(öBJ(öBF(öBB(öB>(öB:(öB6(öB2(öB.(öB*(öB&(öB"(öB
+(öB(öB(öB(öB(öB
+(öB(öB(öAüQìAôQìAìQìAäQìAÜQìAÔQìAÌQìAÄQìAŒQìAŽQìA¬QìA€QìAQìAQìAQìAQìAx£×Ah£×AX£×AH£×A8£×A(£×A£×A£×@ñG®@ÑG®@±G®@G®@b\@"\?Å
+ž?
+=qB~33Bz33Bv33Br33Bn33Bj33Bf33Bb33B^33BZ33BV33BR33BN33BJ33BF33BB33B>33B:33B633B233B.33B*33B&33B"33B
+33B33B33B33B33B
+33B33B33AüffAôffAìffAäffAÜffAÔffAÌffAÄffAŒffAŽffA¬ffA€ffAffAffAffAffAxÌÍAhÌÍAXÌÍAHÌÍA8ÌÍA(ÌÍAÌÍAÌÍ@ñ@Ñ@±@@c33@#33?Æff?
+ÌÍB~=qBz=qBv=qBr=qBn=qBj=qBf=qBb=qB^=qBZ=qBV=qBR=qBN=qBJ=qBF=qBB=qB>=qB:=qB6=qB2=qB.=qB*=qB&=qB"=qB
+=qB=qB=qB=qB=qB
+=qB=qB=qAüzáAôzáAìzáAäzáAÜzáAÔzáAÌzáAÄzáAŒzáAŽzáA¬záA€záAzáAzáAzáAzáAxõÃAhõÃAXõÃAHõÃA8õÃA(õÃAõÃAõÃ@ñë
+@Ñë
+@±ë
+@ë
+@c×
+@#×
+?Ç®?\)B~G®BzG®BvG®BrG®BnG®BjG®BfG®BbG®B^G®BZG®BVG®BRG®BNG®BJG®BFG®BBG®B>G®B:G®B6G®B2G®B.G®B*G®B&G®B"G®B
+G®BG®BG®BG®BG®B
+G®BG®BG®Aü\Aô\Aì\Aä\AÜ\AÔ\AÌ\AÄ\AŒ\AŽ\A¬\A€\A\A\A\A\Ay
+žAi
+žAY
+žAI
+žA9
+žA)
+žA
+žA	
+ž@ò=q@Ò=q@²=q@=q@dzá@$zá?ÈõÂ?ë
+B~QìBzQìBvQìBrQìBnQìBjQìBfQìBbQìB^QìBZQìBVQìBRQìBNQìBJQìBFQìBBQìB>QìB:QìB6QìB2QìB.QìB*QìB&QìB"QìB
+QìBQìBQìBQìBQìB
+QìBQìBQìAü£×Aô£×Aì£×Aä£×AÜ£×AÔ£×AÌ£×AÄ£×AŒ£×AŽ£×A¬£×A€£×A£×A£×A£×A£×AyG®AiG®AYG®AIG®A9G®A)G®AG®A	G®@ò\@Ò\@²\@\@e
+ž@%
+ž?Ê=p?záB~\)Bz\)Bv\)Br\)Bn\)Bj\)Bf\)Bb\)B^\)BZ\)BV\)BR\)BN\)BJ\)BF\)BB\)B>\)B:\)B6\)B2\)B.\)B*\)B&\)B"\)B
+\)B\)B\)B\)B\)B
+\)B\)B\)AüžRAôžRAìžRAäžRAÜžRAÔžRAÌžRAÄžRAŒžRAŽžRA¬žRA€žRAžRAžRAžRAžRAyp€Aip€AYp€AIp€A9p€A)p€Ap€A	p€@òáH@ÒáH@²áH@áH@eÂ@%Â?Ë
+
+?
+=B~ffBzffBvffBrffBnffBjffBfffBbffB^ffBZffBVffBRffBNffBJffBFffBBffB>ffB:ffB6ffB2ffB.ffB*ffB&ffB"ffB
+ffBffBffBffBffB
+ffBffBffAüÌÍAôÌÍAìÌÍAäÌÍAÜÌÍAÔÌÍAÌÌÍAÄÌÍAŒÌÍAŽÌÍA¬ÌÍA€ÌÍAÌÍAÌÍAÌÍAÌÍAyAiAYAIA9A)AA	@ó33@Ó33@³33@33@fff@&ff?ÌÌÍ?B~p€Bzp€Bvp€Brp€Bnp€Bjp€Bfp€Bbp€B^p€BZp€BVp€BRp€BNp€BJp€BFp€BBp€B>p€B:p€B6p€B2p€B.p€B*p€B&p€B"p€B
+p€Bp€Bp€Bp€Bp€B
+p€Bp€Bp€AüáHAôáHAìáHAäáHAÜáHAÔáHAÌáHAÄáHAŒáHAŽáHA¬áHA€áHAáHAáHAáHAáHAyÂAiÂAYÂAIÂA9ÂA)ÂAÂA	Â@ó
+@Ó
+@³
+@
+@g
+>@'
+>?Î{?
+(öB~záBzzáBvzáBrzáBnzáBjzáBfzáBbzáB^záBZzáBVzáBRzáBNzáBJzáBFzáBBzáB>záB:záB6záB2záB.záB*záB&záB"záB
+záBzáBzáBzáBzáB
+záBzáBzáAüõÃAôõÃAìõÃAäõÃAÜõÃAÔõÃAÌõÃAÄõÃAŒõÃAŽõÃA¬õÃA€õÃAõÃAõÃAõÃAõÃAyë
+Aië
+AYë
+AIë
+A9ë
+A)ë
+Aë
+A	ë
+@ó×
+@Ó×
+@³×
+@×
+@g®@'®?Ï\)?
+žRB~
+Bz
+Bv
+Br
+Bn
+Bj
+Bf
+Bb
+B^
+BZ
+BV
+BR
+BN
+BJ
+BF
+BB
+B>
+B:
+B6
+B2
+B.
+B*
+B&
+B"
+B
+
+B
+B
+B
+B
+B
+
+B
+B
+Aý
+=Aõ
+=Aí
+=Aå
+=AÝ
+=AÕ
+=AÍ
+=AÅ
+=Aœ
+=Aµ
+=A­
+=A¥
+=A
+=A
+=A
+=A
+
+=Az{Aj{AZ{AJ{A:{A*{A{A
+{@ô(ö@Ô(ö@Ž(ö@(ö@hQì@(Qì?Ð£×?!G®                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                  -32 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   91 / length of data axis 1                          NAXIS2  =                   91 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B| XB{Ýf¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|ÔB{äþBy	¬Bv5@¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|
+OB{óyBy(Bv<ÖBsaBp¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|+ÊB|õBy&£BvKQBsp Bp®Bm¹\Bjäð¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|:FB|pBy5
+BvYÍBs~{Bp£)BmÇ×BjìBh4Be<È¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|HÁB|
+ëByCBvhHBsöBp±¥BmÖSBjûBh¯BeD^Bbi
+B_ ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|W<B|-gByRBvvÃBsrBpÀ BmäÎBk	}Bh.+BeRÙBbwB_6B\ÀäBYìx¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|e·B|;âBy`Bv
+?Bs©íBpÎBmóJBkøBh<ŠBeaUBbB_ª±B\Ï_BYôBWŒBTDP¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|t3B|J]Byo
+BvºBsžhBpÝBnÅBk&sBhK"BeoÐBb~B_¹-B\ÝÛBZBW'7BTKæBQpBN(¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|®B|XØBy}Bv¢5BsÆãBpëBn@Bk4ïBhYBe~KBb¢úB_ÇšB\ìVBZBW5³BTZaBQBN£ŸBKÈlBHô ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|)B|gTByBv°°BsÕ_Bpú
+Bn
+»BkCjBhhBeÇBb±uB_Ö#B\úÒBZBWD.BThÝBQBN²9BKÖçBHûBF DBCKØ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|¥B|uÑByBv¿.BsãÜBqBn-9BkQçBhvBeDBb¿òB_ä¡B]	OBZ-ýBWR¬BTwZBQBNÀ·BKåeBI
+BF.ÁBCSpB@x
+B=£²¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|®B|LByšûBvÍ©BsòWBqBn;ŽBk`bBh
+Be©¿BbÎmB_ó
+B]ÊBZ<yBWa'BT
+ÕBQªBNÏ2BKóàBIBF==BCaëB@B=«HB:ÏöB7û¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|ŒB|ÇBy·uBvÜ$Bt ÓBq%BnJ/BknÞBhBež:BbÜéB`B]&EBZJôBWo¢BTQBQžÿBNÝ­BL\BI'
+BFKžBCpgB@B=¹ÃB:ÞqB8 B5'ÎB2Sb¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|ËB|¡BByÅñBvêBtMBq3üBnX«Bk}YBh¢BeÆ¶BbëdB`B]4ÁBZYoBW~
+BT¢ÌBQÇzBNì)BL×BI5
+BFZ4BC~âB@£B=È?B:ìíB8B56IB2ZøB/ŠB,«:¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|ÙB|¯ŸByÔlBvùBt
+ÉBqBwBng%BkÔBh°BeÕ1BbùßB`
+B]C<BZgêBWBT±GBQÕõBNú€BLRBIDBFh¯BC]B@²
+B=ÖºB:ûhB8 B5DÅB2isB/!B,²ÐB)×~B'¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|è
+B|Ÿ9ByâçBwBt,DBqPòBnu¡BkOBhŸýBeã¬Bc[B`-	B]Q·BZvfBWBT¿ÂBQäqBO	BL-ÍBIR|BFw*BCÙB@ÀB=å5B;	äB8.B5S@B2wïB/B,ÁKB)åùB'
+šB$/VB!Zê¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B|öB|ÌµByñcBwBt:¿Bq_nBn
+BkšÊBhÍyBeò'BcÕB`;B]`3BZáBW©BTÎ>BQòìBOBL<IBI`÷BF
+¥BCªTB@ÏB=ó±B;_B8=
+B5aŒB2jB/«B,ÏÇB)ôuB'#B$=ÑB!bB
+.B²Â¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}B|Û0ByÿÞBw$BtI;BqméBnBk·FBhÛôBf ¢Bc%QB`IÿB]n­BZ\BWž
+BTÜ¹BRgBO&BLJÄBIorBF!BCžÏB@Ý}B>,B;&ÚB8KB5p7B2åB/¹B,ÞBB*ðB''B$LMB!pûB
+©BºXBßB
+¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}B|é«BzYBw3BtW¶Bq|eBn¡BkÅÁBhêoBf
+Bc3ÌB`XzB]})BZ¡×BWÆ
+BTë4BRãBO4BLY?BI}îBF¢BCÇJB@ëùB>§B;5UB8ZB5~²B2£aB/ÈB,ìœB*lB'6B$ZÈB!wB
+€%BÈÓBíB0B6ÞBbr¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}!úB|ø&Bz
+ÕBwABtf1BqàBn¯BkÔ=BhøëBf
+BcBGB`föB]€BZ°RBWÕBTù¯BR
+]BOC
+BLg»BIiBF±BCÕÆB@útB>"B;CÑB8hB5-B2±ÜB/ÖB,û9B*çB'DB$iDB!òB
+² B×OBûýB «BEYBjB
+¶B
+ºJ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}0uB}€Bz+RBwP Btt¯Bq]BnŸ
+BkâºBihBf,BcPÅB`usB]!BZŸÐBWã~BU,BR,ÛBOQBLv7BIæBF¿BCäCBAñB>- B;RNB8vüB5«B2ÀYB/åB-	¶B*.dB'SB$wÁB!oB
+Á
+BåÌB
+zB/)BS×Bx
+B
+3B
+ÁâBæB$¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}>ñB}Bz9ÍBw^|Bt*Bq§ØBnÌBkñ5BiãBf:Bc_@B`ïB]šBZÍKBWñùBUšBR;VBO`BL³BI©aBFÎBCòŸBAmB><B;`ÉB8
+xB5ª&B2ÎÔB/óB-1B*<ßB'aB$<B!ªëB
+ÏBôGBöB=€BbRBB
+«¯B
+Ð]Bõ
+BºB>hAþÓø¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}MlB}#BzHIBwl÷Bt¥Bq¶TBnÛBkÿ°Bi$_BfI
+Bcm»B`jB]·BZÛÇBX uBU%#BRIÑBOnBL.BI·ÜBFÜBD9BA%çB>JB;oEB8óB5ž¡B2ÝPB0þB-&¬B*K[B'p	B$·B!¹fB
+ÞB
+ÃB'qBLBpÎB|B
+º*B
+ÞÙBB(5BLãAþã#Aù,Aóš¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}[çB}2BzVÄBw{rBt !BqÄÏBné}Bl,Bi2ÚBfWBc|7B` åB]ÅBZêBBXðBU3BRXMBO|ûBL¡©BIÆXBFëBDŽBA4cB>YB;}¿B8¢nB5Ç
+B2ëËB0yB-5(B*YÖB'~B$£3B!ÇáB
+ìB
+>B5ìBZBIB£÷B
+ÈŠB
+íTBB6±B[_Aÿ AùIwAóÔAíÜ1Aè3X¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}jbB}@Bze?BwîBt®BqÓJBn÷ùBl
+§BiAUBffBc²B`¯`B]ÔBZøœBX
+kBUBBRfÈBOwBL°%BIÔÓBFùBD
+0BABÞB>gB;;B8°éB5ÕB2úFB0
+õB-C£B*hQB' B$±®B!Ö\B
+û
+B
+¹BDgBiBÄB²sB
+×!B
+ûÏB ~BE,BiÚAÿ
+AùfnAó¯ËAíù'AèBAâáAÜã¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}xÝB}O
+BzsºBwhBtœBqáÆBotBl+"BiOÑBftBc-B`œÜB]âB[8BX+çBUPBRuCBOòBLŸ BIãOBGýBD,«BAQYB>vB;¶B8¿dB5äB3ÁB0-oB-R
+B*vÍB'{B$À)B!äØB	B
+.4BRãBwB?BÀîB
+åB
+
+KB.ùBS§BxVAÿ:AùeAóÌÂAî
+Aè_{Aâš×AÜò4A×;AÑž¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}YB}]Bz5BwŠäBtËBqð@BoïBl9Bi^LBfúBc§©B`ÌWB]ñB[ŽBX:bBU_BR¿BOšmBLÍBIñÊBGxBD;'BA_ÕB>B;©1B8ÍàB5òB3<B0;ëB-`B*
+GB'©öB$Î¥B!óSBB
+<°Ba^B
+Bª»BÏiB
+ôB
+ÆB=tBb#BÑAÿVÿAù [Aóé·Aî3Aè|rAâÅÎAÝ+A×XAÑ¡äAËëAAÆBh¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}ÔB}lBz±Bwµ_BtÚ
+BqþŒBo#jBlHBilÇBfvBc¶$B`ÚÒB]ÿB[$/BXHÝBUmBR:BO¶èBLÛBJ EBG$óBDI¢BAnPB>ÿB;·­B8Ü[B6	B3%žB0JfB-oB*ÃB'žqB$ÝB"ÎB&}B
+K+BoÙBB¹6BÝäBB
+'ABKïBpBLAÿsõAùœQAô®AîP
+AègAââÅAÝ,"A×u~AÑŸÛAÌ7AÆQAÀñAºò¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}€OB}z~Bz,BwÃÚBtèBr
+7Bo1åBlVBi{BBfðBcÄB`éNB^
+üB[2ªBXWYBU|BR µBOÅdBLêBJÀBG3oBDX
+BA|ËB>¡zB;Æ(B8ê×B6
+B343B0XáB-}B*¢>B'ÆìB$ëB"IB4÷B
+YŠB~UB£BÇ±Bì`BB
+5ŒBZkBB£ÇAÿëAùÚHAô#¥AîmAè¶^Aâÿ»AÝIA×uAÑÛÒAÌ%.AÆnAÀ·çA»DAµJ¡A¯¡È¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}²ÊB}ùBz­§BwÒVBt÷Br²Bo@aBleBiœBf®lBcÓB`÷ÈB^
+wB[A&BXeÔBUBR¯1BOÓßBLøBJ
+<BGAêBDfBAGB>¯õB;Ô£B8ùRB6
+ B3B¯B0g]B-
+B*°¹B'ÕhB$úB"
+ÄBCsB
+h!BÏB±~BÖ-BúÛBB
+D8BhæBB²CAÿ­âAù÷?Aô@AîøAèÓUAã
+±AÝfA×¯kAÑøÇAÌB%AÆAÀÔÞA»
+;AµgA¯°ôA©úQA€Qx¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}ÁFB}vBzŒ$BwàÓBuBr*0BoNÞBlsBi;BfŒéBcáBaFB^*ôB[O¢BXtQBU BRœ®BOâ\BM
+BJ+¹BGPgBDuBAÄB>ŸrB;ã!B9ÏB6,}B3Q,B0uÚB-B*¿7B'ãåB%B"-BBQðB
+vBMB¿ûBä©B	XB.B
+RµBwcBBÀÀAÿÊÜAú9Aô]AîŠóAèðOAã9¬AÝ	A×ÌeAÒÂAÌ_AÆš{AÀñÙA»;6AµA¯ÍïAªKA€`šAªA,¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}ÏÁB}¥òBzÊ BwïNBuüBr8«Bo]YBlBiŠ¶BfËdBcðBaÁB^9oB[^
+BXÌBU§zBRÌ)BOðØBMBJ:4BG^ãBDBAš?B>ÌîB;ñB9JB6:ùB3_§B0UB-©B*Í²B'òaB%B";œB`kB
+
+B©ÈBÎvBó%BÓB<B
+a0B
+ßBªBÏ;AÿçÓAú10AôzAîÃéAé
+FAãV£AÝÿA×é\AÒ2¹AÌ|AÆÅrAÁÏA»X+Aµ¡A¯êæAª4BA€}AÆûAXAYµA°Ü¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}Þ=B}ŽmBzÙBwýÊBu"xBrG&BokÔBlBiµ1BfÙàBcþBa#<B^GëB[lBXGBUµöBRÚ€BOÿRBM$BJH°BGm^BD
+BA¶»B>ÛiB< B9$ÆB6ItB3n"B0ÑB-·B*Ü-B( ÜB%%B"J9BnçB
+BžCBÜòB B&NBJýB
+o«BYB¹BÝ·B eAúN&AôAîàßAé*=AãsAÝŒöAØSAÒO¯AÌ
+AÆâiAÁ+ÅA»u"AµŸA°ÛAªQ9A€AãòA-OAv«AÀA	eA`¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}ìžB}ÂèBzçBx
+EBu0óBrU¢BozPBlþBiÃ¬Bfè[Bd
+	Ba1žB^VfB[{BXÃBUÄqBRéBP
+ÎBM2|BJW*BG{ÙBD BAÅ6B>éäB<B93AB6WïB3|B0¡LB-ÅúB*ê©B(WB%4B"XŽB}bB
+¢BÆ¿BëmBB4ÊBYxB
+~&B¢ÕBÇBì1B àAúk
+AôŽyAîýÖAéG3AãAÝÙíAØ#IAÒlŠAÌ¶AÆÿ_AÁHŒA»AµÛuA°$ÒAªn/A€·A éAJFA¢AÜÿA&[AožAyr)An y¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B}û3B}ÑdBzöBxÀBu?oBrd
+BoËBl­zBiÒ(BföÖBdBa@3B^dáB[BX®>BUÒìBR÷BP
+IBM@÷BJeŠBGTBD¯BAÓ±B>ø`B<
+B9AŒB6fkB3B0¯ÇB-ÔvB*ù$B(
+ÒB%BB"g/BÝB
+°BÕ:BùéB
+BCEBgóB
+¢B±PBÕþBú­B [AúAôÑpAïÍAéd)Aã­AÝöãAØ@?AÒAÌÒùAÇ
+VAÁe³A»¯AµølA°AÉAª%A€ÔA
+ßAg;A°AùöACRA¯Ay¬An>ÑAbÑAWÛ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~	®B}ßßB{Bx)<BuMêBrrBoGBl»õBià£BgRBd* BaN®B^s\B[
+BXŒ¹BUáhBSBP*ÄBMOsBJt!BGÏBDœ~BAâ,B?ÚB<+B9P8B6tæB3B0ŸCB-âñB+B(,NB%PüB"uªBYB
+¿BãµBdB-BQÁBvoB
+
+B¿ËBäzB	(B -ÖAú¥
+AôîgAï7ÃAé AãÊ}AÞÙAØ]6AÒŠAÌïïAÇ9MAÁ©A»ÌA¶cA°^¿Aªš
+A€ñyA:ÕA2AÍAëA`IA©ŠAyæAnxŸAc
+yAW3AL0íA@ß=¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~*B}îZB{Bx7·Bu\eBrBo¥ÂBlÊpBiïBgÍBd8{Ba]*B^ØB[ŠBXË4BUïãBSBP9@BM]îBJBG§KBDËùBAð§B?VB<:B9^²B6aB3šB0ÌŸB-ñlB+B(:ÉB%_wB"&BšÔB
+ÍBò1BßB;B`<BêB
+©BÎGBòõB£B <RAúÂAõ
+]AïTºAéAãçsAÞ0ÐAØz-AÒÃAÍ
+æAÇVCAÁA»èýA¶2YA°{¶AªÅA¥oAWÌA¡)Aê
+A3âA}?AÆAzñAn²«AcEeAWØ ALjÛA@ýA5OA*>¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~&¥B}üÕB{!BxF2BujàBrBoŽ=BlØìBiýBg"HBdF÷Bak¥B^SB[µBXÙ°BUþ^BS#
+BPG»BMliBJBGµÆBDÚtBAÿ#B?#ÑB<HB9m.B6ÜB3¶B0Û9B-ÿèB+$B(IDB%móB"¡B·OB
+ÛþB ¬B%ZBJ	Bn·BeB
+žBÜÂBpB&B JÍAúÞ÷Aõ(TAïq±Aé»
+AäjAÞMÇAØ#AÒàAÍ)ÝAÇs9AÁŒAŒóA¶OOA°­Aªâ	A¥+fAtÃAŸA|APÙA5AãAzYÞAnìAcSAX
+AL€ÇAA7A5Ê=A*\÷A
+ï±A¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~5 B~
+QB{/ÿBxT­Buy\Br
+BoÂžBlçgBj
+Bg0ÄBdUrBaz B^ÏB[Ã}BXè+BV
+ÚBS1BPV6BMzäBJBGÄABDèðBB
+B?2LB<VûB9{©B6 WB3ÅB0éŽB.bB+3B(WÀB%|nB"¡
+BÅËB
+êyB'B3ÖBXB}2B¡áB
+ÆBë=BìB4B YHAúûíAõEJAï§AéØAä!aAÞjœAØŽAÒýwAÍFÓAÇ0AÁÙAŒ"éA¶lFA°µ£AªþÿA¥H]A¹AÛA$sAmÏA·,A AzËAo&
+Ac¹@AXKúALÞµAAqoA6)A*äA)AŒYAO@ùúÆ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~CB~ÌB{>zBxc)Bu×Br¬
+BoÑ4BlõâBjBg??BdcíBaB^­JB[ÑøBXö§BVUBS@BPd²BM`BJ®BGÒŒBD÷kBB
+B?@ÈB<evB9$B6®ÓB3ÓB0ø/B.
+ÞB+AB(f:B%éB"¯BÔFB
+øôB
+£BBQBfÿB®B°\B
+Õ
+Bù¹B
+gBCB gÄAûäAõbAAï«AéôúAä>WAÞŽAØÑAÓmAÍcÊAÇ­'AÁöAŒ?àA¶=A°ÒA«öA¥eSA®¯Aø
+AAiAÆAÔ#A
+AzÍžAo`rAcó-AX
+çAM¢AA«\A6>A*ÐÑAcAöFA@ú7v@ã\ë@Ì¹¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B~RB~(IB{LøBxqŠBuTBr»Boß±Bm_Bj)BgMŒBdrjBaB^»ÇB[àvBY$BV)ÒBSNBPs/BMÝBJŒBGá:BEèBB*B?OEB<sóB9¢B6œPB3áþB1­B.+[B+P	B(tžB%fB"ŸBâÃB
+rB, BPÎBu}B+BŸÙB
+ãB	6B,äBQB vAAû5ßAõ;AïÈAêõAä[QAÞ€®AØî
+AÓ7hAÍÅAÇÊ!AÂ~AŒ\ÛA¶Š7A°ïA«8ñA¥MAËªAA^cA§ÁAñ
+A:zA{­AohAd-"AX¿ÜAMRAAåQA6x
+A+
+ÆAA0;AÂõ@ú«a@ãÐÕ@ÌöJ@¶¿@x^¿  ¿  ¿  ¿  ¿  ¿  B~`B~6ÅB{[sBx!Bu€ÐBrÉ~Boî,BmÛBj7Bg\7BdæBa¥B^ÊBB[îñBYBV8NBS\üBPªBMŠYBJËBGïµBEdBB9B?]ÀB<nB9§
+B6ËËB3ðzB1(B.9ÖB+^
+B(3B%§áB"ÌBñ>B
+ìB:B_JBøBšŠBÍUB
+òB	±B;`B`B ŒAûRÕAõ2AïåAê.ëAäxHAÞÁ¥AÙ
+AÓT^AÍ»AÇçAÂ0uAŒyÑA¶Ã.A±
+A«UçA¥DAè¡A1ýA{ZAÄ·AAWqA{AAoÔUAdgAXùÊAMAB>A6±ùA+D³A×nAj(Aüã@û:@äD¯@Íj$@¶@µ@Ú@dnD¿  ¿  ¿  ¿  B~o
+B~E?B{iîBxBu³KBr×ùBoüšBm!VBjFBgj³BdaBaŽB^ØŸB[ýlBY"BVFÉBSkwBP&BMŽÔBJÙBGþ1BE"ßBBGB?l<B<êB9µB6ÚFB3þõB1#£B.HRB+m B(®B%¶]B"Û
+Bÿ¹B
+$hBIBmÄBsB·"BÛÐB
+ ~B	%-BIÛBnB 8AûoÌAõ¹)Að
+AêKâAä?AÞÞAÙ'øAÓqUAÍº±AÈAÂMkAŒÈA¶à%A±)A«rÞA¥Œ;A ANôAQAá­A+
+AtgA{{ApBAd üAY3·AMÆqABY,A6ëæA+~ A [A€A	6Ð@û@äž@ÍÝþ@·s@ (è@N]@dç€@72@	ëÊ¿  ¿  B~}B~S»B{xiBxBuÁÆBræuBp
+#Bm/ÑBjTBgy.BdÜBaÂB^ç9B\
+çBY0BVUDBSyòBP¡BMÃOBJçþBH
+¬BE1ZBBV	B?z·B<eB9ÄB6èÂB4
+pB12
+B.VÍB+{{B( *B%ÄØB"éB 5B
+2ãBWB|@B îBÅBêKB
+úB	3šBXVB}B ¡³AûÂAõÖAð|AêhÙAä²5AÞûAÙDïAÓKAÍ×šAÈ!AÂjaAŒ³ŸA¶ýA±FxA«ÕA¥Ù1A "AkëAµGAþ€AHA]A{µtApH/AdÚéAYm€AN ^ABA7%ÓA+žA KHAÞA	pœ@üï@å,d@ÎQÙ@·wM@ Â@Â7@eÏX@8A@
+e)?¹`%?=¥@B~
+B~b7B{äBx«BuÐABrôïBpBm>MBjbûBg©Bd¬XBaÑB^õŽB\cBY?BVc¿BSnBP­
+BMÑÊBJöyBH'BE?ÖBBdB?2B<­áB9ÒB6÷=B4ìB1@B.eHB+öB(®¥B%ÓSB"øB 
+°B
+A^Bf
+B»B¯iBÔBøÆB
+
+tB	B#BfÒBB °.Aû©¹AõóAð<rAê
+ÏAäÏ,AßAÙaåAÓ«BAÍôAÈ=ûAÂXAŒÐµA·A±cnA«¬ËA¥ö(A ?
+AáAÒ>AAd÷A®TA{ïaAp
+Ae×AY§AN:KABÍA7_ÀA+ò{A 
+5AðA	ªª@üzÉ@å >@ÎÅ³@·ë(@¡@6@f·
+@9õ@
+LÞ?»/??Ÿ=
+f$¿  B{{BxºBuÞŒBskBp(BmLÇBjqvBg%BdºÓBaßB_0B\(ÞBYMBVr;BSéBP»BMàFBKôBH)¢BENQBBrÿB?®B<Œ\B9á
+B7¹B4*gB1OB.sÄB+rB(œ B%áÎB#}B ++B
+OÚBtB6BœåBâBAB
++ðB	PBuLBûB ŸªAûÆ¯Aö
+AðYiAê¢ÅAäì"Aß5AÙ~ÜAÓÈ9AÎAÈZòAÂ€OAŒí«A·7A±eA«ÉÁAŠ
+A \{A¥ØAï5A8AîAËKA|)OApŒ	AeNÃAYá~ANt9ACóA7­A,,hA ¿"AQÝA	ä@üî£@æ@Ï9@ž_@¡w@©ì@gÁ@9é©@
+4?Œþö?C)=ES?;ò¿
+¿  ¿  BuæSBsçBp6Bm[CBjñBg€BdÉNBaíýB_«B\7YBY\BV¶BS¥dBPÊBMîÁBKoBH8
+BE\ÌBBzB?Š)B<Ê×B9ïB74B48âB1]B.?B+ŠíB(ËB%ðJB#øB 9ŠB
+^UBB§²BÌ`BñBœB
+:kB	_BÈBšvB Í$AûãŠAö-Aðv_Aê¿ŒAå	AßRuAÙÒAÓå/AÎ.AÈwéAÂÁEAœ
+¢A·SÿA±[A«æžAŠ0A yqAÂÎA
++AUAåAèAA|c<ApõöAe±AZkAN®%AC@àA7ÓA,fUA ùAÊA
+
+@ýb}@æò@Ï­g@žÒÜ@¡øQ@
+Æ@hu@:Ñ^@
+
+G?ŸÎ_?FÈa=@Y<°ø¿  ¿  ¿  ¿  Bp>,BmiÀBjmBg³
+Bd×ÊBaüxB_!'B\EÖBYjBV2BS³áBPØBMý=BK!ìBHFBEkHBB÷B?Ž¥B<ÙSB9þB7"°B4G_B1l
+B.»B+µjB(ÚB%þÆB##uB H#B
+lÑBB¶.BÚÜBÿB$9B
+HçB	mBDB¶òB Û¡Aü AöIûAðXAêÜµAå&AßonAÙžËAÔ'AÎKAÈáAÂÞ>Aœ'A·p÷A±ºTA¬±AŠM
+A jAßÇA)#ArA»ÝA:A|-Aq/çAeÂ¢AZU\ANèACzÑA8
+A, FA!3AÅ»A
+Xu@ýÖ_@æûÔ@Ð!I@¹FŸ@¢l3@š@in9@;¹"@
+?Àç?Jgr=º=2¿  ¿  ¿  ¿  ¿  ¿  BjBgÁBdæEBb
+ôB_/¢B\TPBYxÿBV®BSÂ\BPç
+BN
+¹BK0gBHUBEyÄBBrB?Ã B<çÏB:
+}B71+B4UÚB1zB.7B+ÃåB(èB&
+BB#1ðB VB
+{MBûBÄ©BéWBB2ŽB
+WcB	|B ¿BÅnB ê
+Aü
+AöfòAð°OAêù«AåCAßeAÙÕÁAÔ
+AÎh{AÈ±×AÂû4AœDA·îA±×KA¬ §AŠjA ³aAüœAFAwAØÓA"0A|×AqiÔAeüAZIAO"ACŽŸA8GyA,Ú3A!líAÿšA
+c@þJ:@ço¯@Ð#@¹º@¢à
+@@jUî@< Ö@ë¿?ÂmQ?ND=¹F=L1¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BdíÜBboB_>
+B\bÌBYzBV¬(BSÐ×BPõBN4BK>âBHcBE?BB¬íB?ÑB<öJB:øB7?§B4dUB1B.­²B+Ò`B(÷B&œB#@kB eB
+ÈB®vBÓ%B÷ÓB
+BA/B
+eÞB	B¯;BÓéB øAü:AöèAðÍEAë¢Aå_ÿAß©[AÙòžAÔ<AÎ
+qAÈÎÎAÃ+AœaA·ªäA±ôAA¬=AŠûA ÐWAŽAcA¬mAõÊA?'A}Aq£ÂAf6|AZÉ6AO[ðACî«A8fA- A!ŠÛA9A
+ÌO@þŸ@çã@Ñý@º.r@£Sç@y\@k=¢@=@Ós?Ä<¹?Q¥=Ö
+Ê=¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B_EŽB\qGBYõBVº€BSßRBQ BN(¯BKM^BHr
+BEºBB»iB?àB=ÅB:)tB7N"B4rÐB1B.Œ-B+àÛB)B&*8B#NçB sB
+CBŒòBá BNB*ýBO«B
+tYB	Bœ¶BâdBAüWAö ßAðê;Aë3Aå|õAßÆRAÚ¯AÔY
+AÎ¢hAÈëÅAÃ5!Aœ~~A·ÇÛA²7A¬ZAŠ£ñA íNA6«AAÉdAÁA\
+A}JôAqÝ®AfpiA[$AOÞAD(A8»RA-N
+A!àÈAsA
+=@ÿ1î@èWc@Ñ|Ø@º¢L@£ÇÁ@í6@l%V@>p?@»(?Æ
+!?UCç=ó|V=ü§¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BYBVÉBSíÍBQ|BN7*BK[ØBHBE¥6BBÉäB?îB=AB:7ïB7\B4LB1¥úB.ÊšB+ïWB)B&8³B#]bB B
+Š¿BËmBðBÊB9xB^&B
+ÕB	§BÌ1BðßBAütyAöœÕAñ2AëPAåëAßãHAÚ,¥AÔvAÎ¿_AÉ»AÃRAœuA·äÑA²..A¬wAŠÀçA¡
+DAS¡AþAæ[A/·AyA}áArAfªVA[=AOÏËADbA8õ@A-úA"ŽA­oA
+@*@ÿ¥È@èË=@Ñð²@»'@€;@a@m
+
+@?Wô@¢Ü?ÇÛ?Xâž>9r=Œó5¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BSõeBQ øBNEŠBKjUBHBE³±BBØ`B?ýB=!œB:FkB7kB4ÈB1ŽvB.Ù%B+ýÓB)"B&G0B#kÞB B
+µ;BÙéBþB#FBGôBl£B
+QB	µÿBÚ®Bÿ\B$
+AüqAöÚÎAñ$+AëmAå¶äAà AAÚIAÔúAÎÜWAÉ%ŽAÃoAœžmAžÊA²K'A¬AŠÝàA¡'=ApA¹öASAL°A
+A}ŸÓArQAfäGA[wAP	ŒADvA9/1A-ÁìA"TŠAç`A
+zA 
+Õ@é?@Òd@»	@€¯~@Ôó@môÐ@@?ž@¡?É«?\Ê>µž=ÙéÁ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BNM=BKxÐBH~BEÂ-BBæÛB@
+B=08B:TçB7yB4CB1ÂòB.ç B,
+NB)0ýB&U«B#zYB B
+Ã¶BèdB
+B1ÁBVpB{
+B
+ÌB	Ä{Bé)B
+×B2Aü®hAö÷ÅAñA!Aë~AåÓÛAà
+7AÚfAÔ¯ñAÎùMAÉBªAÃAœÕdAž
+ÁA²h
+A¬±zAŠú×A¡D3AAÖíA IAiŠA³A}øÀArzAg
+5A[°ïAPC©ADÖdA9i
+A-ûØA"A!NA
+ŽA FÂ@é²ù@ÒØn@»ýã@¥#X@HÍ@nÜ@A'm@rV?Ëz|?` >%0þ=öàN¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BH¥BEÐšBBõVB@B=>³B:caB7B4¬¿B1ÑmB.öB,ÊB)?xB&d&B#ÕB ­B
+Ò1BöàBB@<BdëBB
+®HB	ÒöB÷€B
+SBAAüË_A÷ŒAñ^Aë§uAåðÑAà:.AÚAÔÌçAÏDAÉ_¡AÃšýAœòZAž;·A²
+A¬ÎqA§ÍA¡a*AªAóãA=@AAÏùA~2¬ArÅgAgX!A[êÜAP}AEQA9£
+A.5ÆA"ÈA[:A
+íõA °@ê&Ô@ÓLH@Œqœ@¥2@Œ§@oÄ8@B!@Z
+?ÍIå?c¿m>3¬E>	ëm¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BBüíB@(B=M.B:qÝB7B4»9B1ßèB/B,)EB)MóB&r¢B#PB »þB
+à­B[B*	BNžBsfBB
+ŒÃB	áqB B*ÎBO|AüèUA÷1±Añ{AëÄlAæ
+ÈAàW%AÚ AÔéÞAÏ3;AÉ|AÃÅôAŸQAžX­A²¢
+A¬ëgA§4ÄA¡~!AÇ}AÚAZ7A£AìðA~lArÿTAgA\$ÉAP·AEJ>A9ÜùA.o³A#mA(A
+'âA º@ê®@ÓÀ"@Œå@Š
+
+@0@p«í@BöÖ@AŸ?ÏN?g^>>B'>fŽ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B=TÅB:XB7¥B4ÉµB1îcB/B,7ÀB)\oB&
+B#¥ËB ÊzB
+ï(BÖB8
+B]3BáBŠB
+Ë>B	ïìBB9IB]øAýKA÷NšAñAëáaAæ*¿Aàt
+AÚœxAÕÕAÏP1AÉAÃâëAŸ,GAžu€A²¿A­]A§QºA¡AätA-ÑAw-AÀA
+	çA~ŠAs9AAgËüA\^¶APñqAE+A:åA.© A#<[AÏA
+aÏA ô@ë@Ô3ý@œYr@Š~æ@€\@q¡@CÞ@)s?Ðè·?jý>P¢Ó>&áû¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B7¬B4Ø1B1üßB/!B,F<B)jêB&B#ŽHB ØöB
+ý€B"SBGBk¯B^Bµ
+B
+ÙºB	þiB#BGÅBltAý"DA÷k¡AñŽýAëþZAæG·AàAÚÚqAÕ#ÎAÏm*AÉ¶AÃÿãAŸI@AžA²ÛùA­%VA§n³A¡žAlAJÉA&AÝA
+&ßA~àxAss2AhíA\§AQ+bAEŸ
+A:P×A.ãA#vKA	A
+ÁA.{@ëk@Ô§ß@œÍT@ŠòÉ@>@r{e@DÆO@7?Òž@?n#>_>5]C¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B2vB/0	B,T·B)yfB&B#ÂÂB çqB
+
+ B0ÎBU|Bz+BÙBÃB
+è6B
+
+äB1BVABzïAý?;A÷AñÑôAìQAæd­Aà®
+AÚ÷gAÕ@ÃAÏ!AÉÓ~AÄ
+ÚAŸf7Až¯A²øðA­BMA§©A¡ÕA
+cAg¿A±
+AúyA
+CÖAeAs­ Ah?ÚA\ÒAQeOAEø	A:ÄA/
+~A#°9ABóA
+Õ­Ahh@ëöE@Õº@ŸA/@§f£@@sc@E®@øì?Ô©?r:õ>mb>CØ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B,\NB)áB&¬B#Ñ>B õìB
+B?IBcøBŠB­TBÒB
+ö±B
+_B@BdŒBjAý\1A÷¥AñîëAì8GAæ€AàËAÛ]AÕ]ºAÏ§AÉðsAÄ9ÑAŸ-AžÌA³çA­_CA§š A¡ñýA;YA¶AÎAoA
+`ÌATSAsç
+AhyÇA]
+AQ<AF1öA:Ä±A/WkA#ê&A|àA
+A¢U@ìj@Õ@Ÿµ@§Ú~@ÿò@tJÎ@F·@à ?ÖW?uÙÅ>|€>RSÍ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B&Ž&B#ß¹B!gB
+)BMÄBrrB!B»ÐBà~B
+,B
+)ÛBNBs7BæAýy(A÷Â
+Aò
+áAìU>AæAàç÷AÛ1TAÕz±AÏÄ
+AÊ
+jAÄVÇAŸ #AžéA³2ÝA­|:A§ÅA¢óAXPA¡­Aë	A4fA
+}ÃA?At úAh³ŽA]FnAQÙ)AFkäA:þA/XA$$A¶ÍA
+IAÜB@ìÝù@Ön@¿(ã@šNX@sÌ@u2@G}k@ÈT?Ø&z?yx>
+Hv>`Ï¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B!
+þB
+7B\?BîB¥BÊJBîùB
+šB
+8VB]B³BŠaAý
+A÷ß{Aò(ØAìr5Aæ»AáîAÛNKAÕ§AÏáAÊ*aAÄsœAŸœA¹wA³OÓA­1A§âA¢+êAuGAŸ£A AQ]A
+¹AÈ,AtZçAhí¡A]\ARAF¥ÐA;8A/ËFA$^ AðºA
+uA/@íQÓ@ÖwH@¿œ@šÂ2@ç§@v7@He @°	?Ùõã?}i>>oJ\¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  Bc×BjBŽBØÇBýuB
+"#B
+FÒBkB/BŽÝAý³A÷üsAòEÐAì-AæØAá!çAÛkCAÕŽ AÏýýAÊGYAÄ¶AŸÚA¹#oA³lÌA­¶)A§ÿ
+A¢HãA?AÛA$ùAnUA
+·²AAtØAi'A]ºMARMAFßÂA;r|A06A$ñA*¬A
+œfAP @íÅµ@Öë+@À@©6@[@wü@ILä@Í?ÛÅl?[=>Ä>>}Å€¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B»¯BçBB
+ðB
+0B
+UMByûBªBÃYAýÐAøjAòbÇAì¬#AæõAá>ÝAÛ:AÕÑAÐóAÊdPAÄ­­AŸ÷	A¹@fA³ÃA­ÓAš
+|A¢eÙA¯5AøAAïALA
+Ô©A
+AtÎÅAiaA]ô:ARôAG¯A;¬iA0?$A$ÑÞAdA
+÷SA@î9@×_@Àz@©©ï@Ïc@wé°@J4@
+?ÝÕ?*Š>â> v¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BB
+?B
+cÈBwB­%BÑÓAýíAø6aAòœAìÉAçwAá[ÓAÛ¥0AÕîAÐ7êAÊGAÄÊ£A¿ A¹]]A³Š¹A­ðAš9sA¢ÏAÌ,AA^åAšCA
+ñA:üAu²AimA^.'ARÀáAGSA;æVA0yA%
+ËAA1@AÃú@î­j@×Òß@ÀøT@ª
+É@C>@xÑe@K
+M@
+g6?ßd=?ú>¢?
+>^¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  B
+k_BòB» BàOAþ	ûAøSWAòŽAìæAç/mAáxÊAÛÂ'AÖ
+AÐTàAÊ=AÄçA¿0÷A¹zSA³Ã°A®
+
+AšViA¢ÆAé#A2A{ÜAÅ9AAWòAuBAiÕYA^hARúÏAGA< CA0²þA%EžAØsAk-Aýè@ï!D@ØF¹@Ál.@ª£@·@y¹@L@
+Nê?á3Š?
+Éx>©}*>œ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  BÃ7BîÊAþ&ñAøpNAò¹«AíAçLdAáÁAÛß
+AÖ(zAÐq×AÊ»3AÅA¿MíA¹JA³à§A®*Ašs`A¢ŒœAAOvAÓAâ/A+AtéAu|AjGA^¢AS4»AGÇvA<Z1A0ìëA%¥A`A¥A7Õ@ï@Øº@Áà@«}@*ò@z Í@Lë¶@6?ã?á>°ºÍ>Ùb¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  Aþ6AøFAòÖ£Aí  Açi]Aá²¹AÛüAÖEsAÐÏAÊØ,AÅ!A¿jåA¹ŽBA³ýA®FüAšYA¢ÙµA#AloAµËAÿ(AH
+AáAu¶}AjI8A^ÛòASn­AHgA<!A1&ÜA%¹ALQAß
+AqÆ@ð	@Ù.u@ÂSë@«y_@Ô@{@MÓ{@ 
+c?äÒ?hk>·øñ>£¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AòåÏAí<öAçSAáÏ°AÜ
+AÖbiAÐ«ÆAÊõ#AÅ>A¿ÜA¹Ñ9AŽA®còAš­OA¢ö¬A@	AeAÒÂA
+Ae{A®ØAuðjAj%A_ßASšAH;TA<ÎA1`ÉA%óA>AùA«³@ð|Û@Ù¢P@ÂÇÅ@«í9@¯@|pG@N»/@!?æ¢?7Ó>¿6>ªT©¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AçAáìŠAÜ6AÖ`AÐÈœAËAÅ[vA¿€ÓA¹î/AŽ7A®éAšÊEA£¢A\ÿAŠ\Aï¹A9ArAËÏAv*XAjœA_OÌASâAHuAA=üA1¶A&-qAÀ+ARåAå @ððµ@Ú*@Ã;@¬a@@}Wú@O¢ä@!íÌ?èqj?<>Æt6>±J¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AÜE/AÖVAÐå³AË/AÅxmA¿ÁÉAº
+&AŽTA®ßAšç<A£0AyõAÃRA
+¯AV
+AiAèÅAvdEAjöÿA_ºAT
+tAH¯.A=AéA1Ô£A&g^AúAÓA@ñd@Ú@Ã¯y@¬Ôî@úb@~?¯@P@"Õ?ê@Ó?Ö€>Í±Ú>žÏï¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AÐôßAËLAÅcA¿ÞÀAº(
+AŽqyA®ºÖA©3A£MAìAàIA)¥AsAŒ_AŒAv2Ak0íA_Ã§ATVaAHé
+A={ÖA2A&¡KA4AÆÀAYz@ñØi@ÚýÞ@Ä#S@­HÈ@n=@'d@QrM@#œ6?ì<?Š
+>Ôï~>À
+¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AÅ€A¿ûžAºEAŽrA®×ÏA©!+A£jA³åAýAAFAûAÙWA"ŽAvØ#AkjÝA_ýATSAI#
+A=µÇA2HA&Û<AmöA ±Ak@òLK@ÛqÁ@Ä5@­Œª@â@@RZ@$€ú?íßÅ?u>Ü-¢>ÇK5¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AºTAAŽ«hA®ôÅA©>"A£AÐÛA8AcA¬ñAöNA?«AwAk€ËA`7
+ATÊ?AI\úA=ïµA2oA')A§äA:AÍX@òÀ&@Ûå@Å
+@®0
+@Uù@{n@SAÆ@%®?ï¯.?Dÿ>ãkE>ÎÚ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A¯ñA©[A£€uAíÒA7/AAÉèAEA\¡AwKýAkÞžA`qsAU-AIçA>)¡A2Œ\A'OAáÑAtAF@ó4 @ÜYu@Å~ê@®€_@ÉÓ@ïI@T)z@&tc?ñ~?i>êšé>ÕÆ}¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A£³¡A
+ÈAT%AAæßA0;AyAw
+êAl¥A`«_AU>AIÐÕA>cA2öIA'A
+ŸA®yAA3@ó§Û@ÜÍO@ÅòÄ@¯9@=®@c#@U.@'\?óN ?ãÒ>ñæ>Ý!¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AcQAºxAÕAM2AAw¿ØAlRA`åLAUxAJ
+ÁA>|A307A'ÂñA
+U«AèeA{ @ôŽ@ÝA*@Æf@¯@±@Öý@Uøã@(CÌ?õ
+i?³:>ù$1>äAÅ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AAj*A³AwùÈAlAa>AU±øAJD²A>×mA3j'A'üâA
+A"WAµ@ô@Ýµ
+@ÆÚ@¯ÿö@%k@Jß@Và§@)+?öìò?Ã? 1*>ëi¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AÂ³Ax3¶AlÆpAaY*AUëåAJ~ A?ZA3€A(6ÏA
+ÉA\DAîþ@õq@Þ(æ@ÇN[@°sÏ@D@Ÿº@WÈ\@*E?øŒ[?R,?Ïü>òœ
+¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AläÉAaAV%ÒAJžA?KGA3ÞA(pŒA
+vA1A(ë@õwK@ÞÀ@ÇÂ5@°çª@
+@2@X°@*úù?úÃ?!?nÍ>ùú®¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AVD+AJòzA?
+4A4îA(ª©A
+=dAÐ
+AbØ@õë%@ß@È6@±[@ù@Šn@YÄ@+â­?ü[,? ðý?
+
+? )¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A?£A4QàA(äA
+wTA
+AÊ@ö_@ß}@È©ñ@±Ïg@ôÛ@P@Z@,Êr?þ*µ?¢À?¬°?:û¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  A)óA
+±BACüAÖ¶@öÒâ@ßøW@É
+Ì@²CA@hµ@*@[g=@-²&?ÿú
+?€ï?K?ÙÌ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  AbUA€@÷FŒ@àl1@ÉŠ@²·@Ü@
+@\Nò@.Ú@ äÃ?Š_X?êU?
+x¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  @÷n@àà
+@Ê@³*õ@Pj@
+uß@]6Š@/@Ìx?š.Á?'?q¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  @ÊB2@³Ð@ÄD@
+é¹@^
+[@0iC@Ž,?©þ*?
+'ø?¶B¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  @ þ@]@_@1Q@ñ?«Í³? Ç
+?U¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  @_@28œ@¥?­
+?$eÝ?óç¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  @ý	?¯l
+?(®?
+ž¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ?)ê;?!1¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿  ¿                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                  -32 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   64 / length of data axis 1                          NAXIS2  =                   64 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             B~
+B~záB~p€B~ffB~\)B~QìB~G®B~=qB~33B~(öB~
+žB~{B~
+=B~  B}õÃB}ë
+B}áHB}×
+B}ÌÍB}ÂB}žRB}®B}£×B}B}\B}
+B}záB}p€B}ffB}\)B}QìB}G®B}=qB}33B}(öB}
+žB}{B}
+=B}  B|õÃB|ë
+B|áHB|×
+B|ÌÍB|ÂB|žRB|®B|£×B|B|\B|
+B|záB|p€B|ffB|\)B|QìB|G®B|=qB|33B|(öB|
+žB|{B|
+=B|  Bz
+BzzáBzp€BzffBz\)BzQìBzG®Bz=qBz33Bz(öBz
+žBz{Bz
+=Bz  ByõÃByë
+ByáHBy×
+ByÌÍByÂByžRBy®By£×ByBy\By
+ByzáByp€ByffBy\)ByQìByG®By=qBy33By(öBy
+žBy{By
+=By  BxõÃBxë
+BxáHBx×
+BxÌÍBxÂBxžRBx®Bx£×BxBx\Bx
+BxzáBxp€BxffBx\)BxQìBxG®Bx=qBx33Bx(öBx
+žBx{Bx
+=Bx  Bv
+BvzáBvp€BvffBv\)BvQìBvG®Bv=qBv33Bv(öBv
+žBv{Bv
+=Bv  BuõÃBuë
+BuáHBu×
+BuÌÍBuÂBužRBu®Bu£×BuBu\Bu
+BuzáBup€BuffBu\)BuQìBuG®Bu=qBu33Bu(öBu
+žBu{Bu
+=Bu  BtõÃBtë
+BtáHBt×
+BtÌÍBtÂBtžRBt®Bt£×BtBt\Bt
+BtzáBtp€BtffBt\)BtQìBtG®Bt=qBt33Bt(öBt
+žBt{Bt
+=Bt  Br
+BrzáBrp€BrffBr\)BrQìBrG®Br=qBr33Br(öBr
+žBr{Br
+=Br  BqõÃBqë
+BqáHBq×
+BqÌÍBqÂBqžRBq®Bq£×BqBq\Bq
+BqzáBqp€BqffBq\)BqQìBqG®Bq=qBq33Bq(öBq
+žBq{Bq
+=Bq  BpõÃBpë
+BpáHBp×
+BpÌÍBpÂBpžRBp®Bp£×BpBp\Bp
+BpzáBpp€BpffBp\)BpQìBpG®Bp=qBp33Bp(öBp
+žBp{Bp
+=Bp  Bn
+BnzáBnp€BnffBn\)BnQìBnG®Bn=qBn33Bn(öBn
+žBn{Bn
+=Bn  BmõÃBmë
+BmáHBm×
+BmÌÍBmÂBmžRBm®Bm£×BmBm\Bm
+BmzáBmp€BmffBm\)BmQìBmG®Bm=qBm33Bm(öBm
+žBm{Bm
+=Bm  BlõÃBlë
+BláHBl×
+BlÌÍBlÂBlžRBl®Bl£×BlBl\Bl
+BlzáBlp€BlffBl\)BlQìBlG®Bl=qBl33Bl(öBl
+žBl{Bl
+=Bl  Bj
+BjzáBjp€BjffBj\)BjQìBjG®Bj=qBj33Bj(öBj
+žBj{Bj
+=Bj  BiõÃBië
+BiáHBi×
+BiÌÍBiÂBižRBi®Bi£×BiBi\Bi
+BizáBip€BiffBi\)BiQìBiG®Bi=qBi33Bi(öBi
+žBi{Bi
+=Bi  BhõÃBhë
+BháHBh×
+BhÌÍBhÂBhžRBh®Bh£×BhBh\Bh
+BhzáBhp€BhffBh\)BhQìBhG®Bh=qBh33Bh(öBh
+žBh{Bh
+=Bh  Bf
+BfzáBfp€BfffBf\)BfQìBfG®Bf=qBf33Bf(öBf
+žBf{Bf
+=Bf  BeõÃBeë
+BeáHBe×
+BeÌÍBeÂBežRBe®Be£×BeBe\Be
+BezáBep€BeffBe\)BeQìBeG®Be=qBe33Be(öBe
+žBe{Be
+=Be  BdõÃBdë
+BdáHBd×
+BdÌÍBdÂBdžRBd®Bd£×BdBd\Bd
+BdzáBdp€BdffBd\)BdQìBdG®Bd=qBd33Bd(öBd
+žBd{Bd
+=Bd  Bb
+BbzáBbp€BbffBb\)BbQìBbG®Bb=qBb33Bb(öBb
+žBb{Bb
+=Bb  BaõÃBaë
+BaáHBa×
+BaÌÍBaÂBažRBa®Ba£×BaBa\Ba
+BazáBap€BaffBa\)BaQìBaG®Ba=qBa33Ba(öBa
+žBa{Ba
+=Ba  B`õÃB`ë
+B`áHB`×
+B`ÌÍB`ÂB`žRB`®B`£×B`B`\B`
+B`záB`p€B`ffB`\)B`QìB`G®B`=qB`33B`(öB`
+žB`{B`
+=B`  B^
+B^záB^p€B^ffB^\)B^QìB^G®B^=qB^33B^(öB^
+žB^{B^
+=B^  B]õÃB]ë
+B]áHB]×
+B]ÌÍB]ÂB]žRB]®B]£×B]B]\B]
+B]záB]p€B]ffB]\)B]QìB]G®B]=qB]33B](öB]
+žB]{B]
+=B]  B\õÃB\ë
+B\áHB\×
+B\ÌÍB\ÂB\žRB\®B\£×B\B\\B\
+B\záB\p€B\ffB\\)B\QìB\G®B\=qB\33B\(öB\
+žB\{B\
+=B\  BZ
+BZzáBZp€BZffBZ\)BZQìBZG®BZ=qBZ33BZ(öBZ
+žBZ{BZ
+=BZ  BYõÃBYë
+BYáHBY×
+BYÌÍBYÂBYžRBY®BY£×BYBY\BY
+BYzáBYp€BYffBY\)BYQìBYG®BY=qBY33BY(öBY
+žBY{BY
+=BY  BXõÃBXë
+BXáHBX×
+BXÌÍBXÂBXžRBX®BX£×BXBX\BX
+BXzáBXp€BXffBX\)BXQìBXG®BX=qBX33BX(öBX
+žBX{BX
+=BX  BV
+BVzáBVp€BVffBV\)BVQìBVG®BV=qBV33BV(öBV
+žBV{BV
+=BV  BUõÃBUë
+BUáHBU×
+BUÌÍBUÂBUžRBU®BU£×BUBU\BU
+BUzáBUp€BUffBU\)BUQìBUG®BU=qBU33BU(öBU
+žBU{BU
+=BU  BTõÃBTë
+BTáHBT×
+BTÌÍBTÂBTžRBT®BT£×BTBT\BT
+BTzáBTp€BTffBT\)BTQìBTG®BT=qBT33BT(öBT
+žBT{BT
+=BT  BR
+BRzáBRp€BRffBR\)BRQìBRG®BR=qBR33BR(öBR
+žBR{BR
+=BR  BQõÃBQë
+BQáHBQ×
+BQÌÍBQÂBQžRBQ®BQ£×BQBQ\BQ
+BQzáBQp€BQffBQ\)BQQìBQG®BQ=qBQ33BQ(öBQ
+žBQ{BQ
+=BQ  BPõÃBPë
+BPáHBP×
+BPÌÍBPÂBPžRBP®BP£×BPBP\BP
+BPzáBPp€BPffBP\)BPQìBPG®BP=qBP33BP(öBP
+žBP{BP
+=BP  BN
+BNzáBNp€BNffBN\)BNQìBNG®BN=qBN33BN(öBN
+žBN{BN
+=BN  BMõÃBMë
+BMáHBM×
+BMÌÍBMÂBMžRBM®BM£×BMBM\BM
+BMzáBMp€BMffBM\)BMQìBMG®BM=qBM33BM(öBM
+žBM{BM
+=BM  BLõÃBLë
+BLáHBL×
+BLÌÍBLÂBLžRBL®BL£×BLBL\BL
+BLzáBLp€BLffBL\)BLQìBLG®BL=qBL33BL(öBL
+žBL{BL
+=BL  BJ
+BJzáBJp€BJffBJ\)BJQìBJG®BJ=qBJ33BJ(öBJ
+žBJ{BJ
+=BJ  BIõÃBIë
+BIáHBI×
+BIÌÍBIÂBIžRBI®BI£×BIBI\BI
+BIzáBIp€BIffBI\)BIQìBIG®BI=qBI33BI(öBI
+žBI{BI
+=BI  BHõÃBHë
+BHáHBH×
+BHÌÍBHÂBHžRBH®BH£×BHBH\BH
+BHzáBHp€BHffBH\)BHQìBHG®BH=qBH33BH(öBH
+žBH{BH
+=BH  BF
+BFzáBFp€BFffBF\)BFQìBFG®BF=qBF33BF(öBF
+žBF{BF
+=BF  BEõÃBEë
+BEáHBE×
+BEÌÍBEÂBEžRBE®BE£×BEBE\BE
+BEzáBEp€BEffBE\)BEQìBEG®BE=qBE33BE(öBE
+žBE{BE
+=BE  BDõÃBDë
+BDáHBD×
+BDÌÍBDÂBDžRBD®BD£×BDBD\BD
+BDzáBDp€BDffBD\)BDQìBDG®BD=qBD33BD(öBD
+žBD{BD
+=BD  BB
+BBzáBBp€BBffBB\)BBQìBBG®BB=qBB33BB(öBB
+žBB{BB
+=BB  BAõÃBAë
+BAáHBA×
+BAÌÍBAÂBAžRBA®BA£×BABA\BA
+BAzáBAp€BAffBA\)BAQìBAG®BA=qBA33BA(öBA
+žBA{BA
+=BA  B@õÃB@ë
+B@áHB@×
+B@ÌÍB@ÂB@žRB@®B@£×B@B@\B@
+B@záB@p€B@ffB@\)B@QìB@G®B@=qB@33B@(öB@
+žB@{B@
+=B@  B>
+B>záB>p€B>ffB>\)B>QìB>G®B>=qB>33B>(öB>
+žB>{B>
+=B>  B=õÃB=ë
+B=áHB=×
+B=ÌÍB=ÂB=žRB=®B=£×B=B=\B=
+B=záB=p€B=ffB=\)B=QìB=G®B==qB=33B=(öB=
+žB={B=
+=B=  B<õÃB<ë
+B<áHB<×
+B<ÌÍB<ÂB<žRB<®B<£×B<B<\B<
+B<záB<p€B<ffB<\)B<QìB<G®B<=qB<33B<(öB<
+žB<{B<
+=B<  B:
+B:záB:p€B:ffB:\)B:QìB:G®B:=qB:33B:(öB:
+žB:{B:
+=B:  B9õÃB9ë
+B9áHB9×
+B9ÌÍB9ÂB9žRB9®B9£×B9B9\B9
+B9záB9p€B9ffB9\)B9QìB9G®B9=qB933B9(öB9
+žB9{B9
+=B9  B8õÃB8ë
+B8áHB8×
+B8ÌÍB8ÂB8žRB8®B8£×B8B8\B8
+B8záB8p€B8ffB8\)B8QìB8G®B8=qB833B8(öB8
+žB8{B8
+=B8  B6
+B6záB6p€B6ffB6\)B6QìB6G®B6=qB633B6(öB6
+žB6{B6
+=B6  B5õÃB5ë
+B5áHB5×
+B5ÌÍB5ÂB5žRB5®B5£×B5B5\B5
+B5záB5p€B5ffB5\)B5QìB5G®B5=qB533B5(öB5
+žB5{B5
+=B5  B4õÃB4ë
+B4áHB4×
+B4ÌÍB4ÂB4žRB4®B4£×B4B4\B4
+B4záB4p€B4ffB4\)B4QìB4G®B4=qB433B4(öB4
+žB4{B4
+=B4  B2
+B2záB2p€B2ffB2\)B2QìB2G®B2=qB233B2(öB2
+žB2{B2
+=B2  B1õÃB1ë
+B1áHB1×
+B1ÌÍB1ÂB1žRB1®B1£×B1B1\B1
+B1záB1p€B1ffB1\)B1QìB1G®B1=qB133B1(öB1
+žB1{B1
+=B1  B0õÃB0ë
+B0áHB0×
+B0ÌÍB0ÂB0žRB0®B0£×B0B0\B0
+B0záB0p€B0ffB0\)B0QìB0G®B0=qB033B0(öB0
+žB0{B0
+=B0  B.
+B.záB.p€B.ffB.\)B.QìB.G®B.=qB.33B.(öB.
+žB.{B.
+=B.  B-õÃB-ë
+B-áHB-×
+B-ÌÍB-ÂB-žRB-®B-£×B-B-\B-
+B-záB-p€B-ffB-\)B-QìB-G®B-=qB-33B-(öB-
+žB-{B-
+=B-  B,õÃB,ë
+B,áHB,×
+B,ÌÍB,ÂB,žRB,®B,£×B,B,\B,
+B,záB,p€B,ffB,\)B,QìB,G®B,=qB,33B,(öB,
+žB,{B,
+=B,  B*
+B*záB*p€B*ffB*\)B*QìB*G®B*=qB*33B*(öB*
+žB*{B*
+=B*  B)õÃB)ë
+B)áHB)×
+B)ÌÍB)ÂB)žRB)®B)£×B)B)\B)
+B)záB)p€B)ffB)\)B)QìB)G®B)=qB)33B)(öB)
+žB){B)
+=B)  B(õÃB(ë
+B(áHB(×
+B(ÌÍB(ÂB(žRB(®B(£×B(B(\B(
+B(záB(p€B(ffB(\)B(QìB(G®B(=qB(33B((öB(
+žB({B(
+=B(  B&
+B&záB&p€B&ffB&\)B&QìB&G®B&=qB&33B&(öB&
+žB&{B&
+=B&  B%õÃB%ë
+B%áHB%×
+B%ÌÍB%ÂB%žRB%®B%£×B%B%\B%
+B%záB%p€B%ffB%\)B%QìB%G®B%=qB%33B%(öB%
+žB%{B%
+=B%  B$õÃB$ë
+B$áHB$×
+B$ÌÍB$ÂB$žRB$®B$£×B$B$\B$
+B$záB$p€B$ffB$\)B$QìB$G®B$=qB$33B$(öB$
+žB${B$
+=B$  B"
+B"záB"p€B"ffB"\)B"QìB"G®B"=qB"33B"(öB"
+žB"{B"
+=B"  B!õÃB!ë
+B!áHB!×
+B!ÌÍB!ÂB!žRB!®B!£×B!B!\B!
+B!záB!p€B!ffB!\)B!QìB!G®B!=qB!33B!(öB!
+žB!{B!
+=B!  B õÃB ë
+B áHB ×
+B ÌÍB ÂB žRB ®B £×B B \B 
+B záB p€B ffB \)B QìB G®B =qB 33B (öB 
+žB {B 
+=B   B
+
+B
+záB
+p€B
+ffB
+\)B
+QìB
+G®B
+=qB
+33B
+(öB
+
+žB
+{B
+
+=B
+  B
+õÃB
+ë
+B
+áHB
+×
+B
+ÌÍB
+ÂB
+žRB
+®B
+£×B
+B
+\B
+
+B
+záB
+p€B
+ffB
+\)B
+QìB
+G®B
+=qB
+33B
+(öB
+
+žB
+{B
+
+=B
+  B
+õÃB
+ë
+B
+áHB
+×
+B
+ÌÍB
+ÂB
+žRB
+®B
+£×B
+B
+\B
+
+B
+záB
+p€B
+ffB
+\)B
+QìB
+G®B
+=qB
+33B
+(öB
+
+žB
+{B
+
+=B
+  B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  B
+õÃB
+ë
+B
+áHB
+×
+B
+ÌÍB
+ÂB
+žRB
+®B
+£×B
+B
+\B
+
+B
+záB
+p€B
+ffB
+\)B
+QìB
+G®B
+=qB
+33B
+(öB
+
+žB
+{B
+=B
+  B
+õÃB
+ë
+B
+áHB
+×
+B
+ÌÍB
+ÂB
+žRB
+®B
+£×B
+B
+\B
+
+B
+záB
+p€B
+ffB
+\)B
+QìB
+G®B
+=qB
+33B
+(öB
+
+žB
+{B
+
+=B
+  B
+
+B
+záB
+p€B
+ffB
+\)B
+QìB
+G®B
+=qB
+33B
+(öB
+
+žB
+{B
+
+=B
+  B	õÃB	ë
+B	áHB	×
+B	ÌÍB	ÂB	žRB	®B	£×B	B	\B	
+B	záB	p€B	ffB	\)B	QìB	G®B	=qB	33B	(öB	
+žB	{B	
+=B	  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  BõÃBë
+BáHB×
+BÌÍBÂBžRB®B£×BB\B
+BzáBp€BffB\)BQìBG®B=qB33B(öB
+žB{B
+=B  B õÃB ë
+B áHB ×
+B ÌÍB ÂB žRB ®B £×B B \B 
+B záB p€B ffB \)B QìB G®B =qB 33B (öB 
+žB {B 
+=B   Aý
+=AüõÃAüáHAüÌÍAüžRAü£×Aü\AüzáAüffAüQìAü=qAü(öAü{Aü  Aûë
+Aû×
+AûÂAû®AûAû
+Aûp€Aû\)AûG®Aû33Aû
+žAû
+=AúõÃAúáHAúÌÍAúžRAú£×Aú\AúzáAúffAúQìAú=qAú(öAú{Aú  Aùë
+Aù×
+AùÂAù®AùAù
+Aùp€Aù\)AùG®Aù33Aù
+žAù
+=AøõÃAøáHAøÌÍAøžRAø£×Aø\AøzáAøffAøQìAø=qAø(öAø{Aø  Aõ
+=AôõÃAôáHAôÌÍAôžRAô£×Aô\AôzáAôffAôQìAô=qAô(öAô{Aô  Aóë
+Aó×
+AóÂAó®AóAó
+Aóp€Aó\)AóG®Aó33Aó
+žAó
+=AòõÃAòáHAòÌÍAòžRAò£×Aò\AòzáAòffAòQìAò=qAò(öAò{Aò  Añë
+Añ×
+AñÂAñ®AñAñ
+Añp€Añ\)AñG®Añ33Añ
+žAñ
+=AðõÃAðáHAðÌÍAðžRAð£×Að\AðzáAðffAðQìAð=qAð(öAð{Að  Aí
+=AìõÃAìáHAìÌÍAìžRAì£×Aì\AìzáAìffAìQìAì=qAì(öAì{Aì  Aëë
+Aë×
+AëÂAë®AëAë
+Aëp€Aë\)AëG®Aë33Aë
+žAë
+=AêõÃAêáHAêÌÍAêžRAê£×Aê\AêzáAêffAêQìAê=qAê(öAê{Aê  Aéë
+Aé×
+AéÂAé®AéAé
+Aép€Aé\)AéG®Aé33Aé
+žAé
+=AèõÃAèáHAèÌÍAèžRAè£×Aè\AèzáAèffAèQìAè=qAè(öAè{Aè  Aå
+=AäõÃAäáHAäÌÍAäžRAä£×Aä\AäzáAäffAäQìAä=qAä(öAä{Aä  Aãë
+Aã×
+AãÂAã®AãAã
+Aãp€Aã\)AãG®Aã33Aã
+žAã
+=AâõÃAâáHAâÌÍAâžRAâ£×Aâ\AâzáAâffAâQìAâ=qAâ(öAâ{Aâ  Aáë
+Aá×
+AáÂAá®AáAá
+Aáp€Aá\)AáG®Aá33Aá
+žAá
+=AàõÃAàáHAàÌÍAàžRAà£×Aà\AàzáAàffAàQìAà=qAà(öAà{Aà  AÝ
+=AÜõÃAÜáHAÜÌÍAÜžRAÜ£×AÜ\AÜzáAÜffAÜQìAÜ=qAÜ(öAÜ{AÜ  AÛë
+AÛ×
+AÛÂAÛ®AÛAÛ
+AÛp€AÛ\)AÛG®AÛ33AÛ
+žAÛ
+=AÚõÃAÚáHAÚÌÍAÚžRAÚ£×AÚ\AÚzáAÚffAÚQìAÚ=qAÚ(öAÚ{AÚ  AÙë
+AÙ×
+AÙÂAÙ®AÙAÙ
+AÙp€AÙ\)AÙG®AÙ33AÙ
+žAÙ
+=AØõÃAØáHAØÌÍAØžRAØ£×AØ\AØzáAØffAØQìAØ=qAØ(öAØ{AØ  AÕ
+=AÔõÃAÔáHAÔÌÍAÔžRAÔ£×AÔ\AÔzáAÔffAÔQìAÔ=qAÔ(öAÔ{AÔ  AÓë
+AÓ×
+AÓÂAÓ®AÓAÓ
+AÓp€AÓ\)AÓG®AÓ33AÓ
+žAÓ
+=AÒõÃAÒáHAÒÌÍAÒžRAÒ£×AÒ\AÒzáAÒffAÒQìAÒ=qAÒ(öAÒ{AÒ  AÑë
+AÑ×
+AÑÂAÑ®AÑAÑ
+AÑp€AÑ\)AÑG®AÑ33AÑ
+žAÑ
+=AÐõÃAÐáHAÐÌÍAÐžRAÐ£×AÐ\AÐzáAÐffAÐQìAÐ=qAÐ(öAÐ{AÐ  AÍ
+=AÌõÃAÌáHAÌÌÍAÌžRAÌ£×AÌ\AÌzáAÌffAÌQìAÌ=qAÌ(öAÌ{AÌ  AËë
+AË×
+AËÂAË®AËAË
+AËp€AË\)AËG®AË33AË
+žAË
+=AÊõÃAÊáHAÊÌÍAÊžRAÊ£×AÊ\AÊzáAÊffAÊQìAÊ=qAÊ(öAÊ{AÊ  AÉë
+AÉ×
+AÉÂAÉ®AÉAÉ
+AÉp€AÉ\)AÉG®AÉ33AÉ
+žAÉ
+=AÈõÃAÈáHAÈÌÍAÈžRAÈ£×AÈ\AÈzáAÈffAÈQìAÈ=qAÈ(öAÈ{AÈ  AÅ
+=AÄõÃAÄáHAÄÌÍAÄžRAÄ£×AÄ\AÄzáAÄffAÄQìAÄ=qAÄ(öAÄ{AÄ  AÃë
+AÃ×
+AÃÂAÃ®AÃAÃ
+AÃp€AÃ\)AÃG®AÃ33AÃ
+žAÃ
+=AÂõÃAÂáHAÂÌÍAÂžRAÂ£×AÂ\AÂzáAÂffAÂQìAÂ=qAÂ(öAÂ{AÂ  AÁë
+AÁ×
+AÁÂAÁ®AÁAÁ
+AÁp€AÁ\)AÁG®AÁ33AÁ
+žAÁ
+=AÀõÃAÀáHAÀÌÍAÀžRAÀ£×AÀ\AÀzáAÀffAÀQìAÀ=qAÀ(öAÀ{AÀ  Aœ
+=AŒõÃAŒáHAŒÌÍAŒžRAŒ£×AŒ\AŒzáAŒffAŒQìAŒ=qAŒ(öAŒ{AŒ  A»ë
+A»×
+A»ÂA»®A»A»
+A»p€A»\)A»G®A»33A»
+žA»
+=AºõÃAºáHAºÌÍAºžRAº£×Aº\AºzáAºffAºQìAº=qAº(öAº{Aº  A¹ë
+A¹×
+A¹ÂA¹®A¹A¹
+A¹p€A¹\)A¹G®A¹33A¹
+žA¹
+=AžõÃAžáHAžÌÍAžžRAž£×Až\AžzáAžffAžQìAž=qAž(öAž{Až  Aµ
+=AŽõÃAŽáHAŽÌÍAŽžRAŽ£×AŽ\AŽzáAŽffAŽQìAŽ=qAŽ(öAŽ{AŽ  A³ë
+A³×
+A³ÂA³®A³A³
+A³p€A³\)A³G®A³33A³
+žA³
+=A²õÃA²áHA²ÌÍA²žRA²£×A²\A²záA²ffA²QìA²=qA²(öA²{A²  A±ë
+A±×
+A±ÂA±®A±A±
+A±p€A±\)A±G®A±33A±
+žA±
+=A°õÃA°áHA°ÌÍA°žRA°£×A°\A°záA°ffA°QìA°=qA°(öA°{A°  A­
+=A¬õÃA¬áHA¬ÌÍA¬žRA¬£×A¬\A¬záA¬ffA¬QìA¬=qA¬(öA¬{A¬  A«ë
+A«×
+A«ÂA«®A«A«
+A«p€A«\)A«G®A«33A«
+žA«
+=AªõÃAªáHAªÌÍAªžRAª£×Aª\AªzáAªffAªQìAª=qAª(öAª{Aª  A©ë
+A©×
+A©ÂA©®A©A©
+A©p€A©\)A©G®A©33A©
+žA©
+=AšõÃAšáHAšÌÍAšžRAš£×Aš\AšzáAšffAšQìAš=qAš(öAš{Aš  A¥
+=A€õÃA€áHA€ÌÍA€žRA€£×A€\A€záA€ffA€QìA€=qA€(öA€{A€  A£ë
+A£×
+A£ÂA£®A£A£
+A£p€A£\)A£G®A£33A£
+žA£
+=A¢õÃA¢áHA¢ÌÍA¢žRA¢£×A¢\A¢záA¢ffA¢QìA¢=qA¢(öA¢{A¢  A¡ë
+A¡×
+A¡ÂA¡®A¡A¡
+A¡p€A¡\)A¡G®A¡33A¡
+žA¡
+=A õÃA áHA ÌÍA žRA £×A \A záA ffA QìA =qA (öA {A   A
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Aë
+A×
+AÂA®AA
+Ap€A\)AG®A33A
+žA
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Aë
+A×
+AÂA®AA
+Ap€A\)AG®A33A
+žA
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  A
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Aë
+A×
+AÂA®AA
+Ap€A\)AG®A33A
+žA
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Aë
+A×
+AÂA®AA
+Ap€A\)AG®A33A
+žA
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  A
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Aë
+A×
+AÂA®AA
+Ap€A\)AG®A33A
+žA
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Aë
+A×
+AÂA®AA
+Ap€A\)AG®A33A
+žA
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  A
+
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Aë
+A×
+AÂA®AA
+Ap€A\)AG®A33A
+žA
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Aë
+A×
+AÂA®AA
+Ap€A\)AG®A33A
+žA
+=AõÃAáHAÌÍAžRA£×A\AzáAffAQìA=qA(öA{A  Az{Ayë
+AyÂAyAyp€AyG®Ay
+žAxõÃAxÌÍAx£×AxzáAxQìAx(öAx  Aw×
+Aw®Aw
+Aw\)Aw33Aw
+=AváHAvžRAv\AvffAv=qAv{Auë
+AuÂAuAup€AuG®Au
+žAtõÃAtÌÍAt£×AtzáAtQìAt(öAt  As×
+As®As
+As\)As33As
+=AráHAržRAr\ArffAr=qAr{Aqë
+AqÂAqAqp€AqG®Aq
+žApõÃApÌÍAp£×ApzáApQìAp(öAp  Aj{Aië
+AiÂAiAip€AiG®Ai
+žAhõÃAhÌÍAh£×AhzáAhQìAh(öAh  Ag×
+Ag®Ag
+Ag\)Ag33Ag
+=AfáHAfžRAf\AfffAf=qAf{Aeë
+AeÂAeAep€AeG®Ae
+žAdõÃAdÌÍAd£×AdzáAdQìAd(öAd  Ac×
+Ac®Ac
+Ac\)Ac33Ac
+=AbáHAbžRAb\AbffAb=qAb{Aaë
+AaÂAaAap€AaG®Aa
+žA`õÃA`ÌÍA`£×A`záA`QìA`(öA`  AZ{AYë
+AYÂAYAYp€AYG®AY
+žAXõÃAXÌÍAX£×AXzáAXQìAX(öAX  AW×
+AW®AW
+AW\)AW33AW
+=AVáHAVžRAV\AVffAV=qAV{AUë
+AUÂAUAUp€AUG®AU
+žATõÃATÌÍAT£×ATzáATQìAT(öAT  AS×
+AS®AS
+AS\)AS33AS
+=ARáHARžRAR\ARffAR=qAR{AQë
+AQÂAQAQp€AQG®AQ
+žAPõÃAPÌÍAP£×APzáAPQìAP(öAP  AJ{AIë
+AIÂAIAIp€AIG®AI
+žAHõÃAHÌÍAH£×AHzáAHQìAH(öAH  AG×
+AG®AG
+AG\)AG33AG
+=AFáHAFžRAF\AFffAF=qAF{AEë
+AEÂAEAEp€AEG®AE
+žADõÃADÌÍAD£×ADzáADQìAD(öAD  AC×
+AC®AC
+AC\)AC33AC
+=ABáHABžRAB\ABffAB=qAB{AAë
+AAÂAAAAp€AAG®AA
+žA@õÃA@ÌÍA@£×A@záA@QìA@(öA@  A:{A9ë
+A9ÂA9A9p€A9G®A9
+žA8õÃA8ÌÍA8£×A8záA8QìA8(öA8  A7×
+A7®A7
+A7\)A733A7
+=A6áHA6žRA6\A6ffA6=qA6{A5ë
+A5ÂA5A5p€A5G®A5
+žA4õÃA4ÌÍA4£×A4záA4QìA4(öA4  A3×
+A3®A3
+A3\)A333A3
+=A2áHA2žRA2\A2ffA2=qA2{A1ë
+A1ÂA1A1p€A1G®A1
+žA0õÃA0ÌÍA0£×A0záA0QìA0(öA0  A*{A)ë
+A)ÂA)A)p€A)G®A)
+žA(õÃA(ÌÍA(£×A(záA(QìA((öA(  A'×
+A'®A'
+A'\)A'33A'
+=A&áHA&žRA&\A&ffA&=qA&{A%ë
+A%ÂA%A%p€A%G®A%
+žA$õÃA$ÌÍA$£×A$záA$QìA$(öA$  A#×
+A#®A#
+A#\)A#33A#
+=A"áHA"žRA"\A"ffA"=qA"{A!ë
+A!ÂA!A!p€A!G®A!
+žA õÃA ÌÍA £×A záA QìA (öA   A{Aë
+AÂAAp€AG®A
+žAõÃAÌÍA£×AzáAQìA(öA  A×
+A®A
+A\)A33A
+=AáHAžRA\AffA=qA{Aë
+AÂAAp€AG®A
+žAõÃAÌÍA£×AzáAQìA(öA  A×
+A®A
+A\)A33A
+=AáHAžRA\AffA=qA{Aë
+AÂAAp€AG®A
+žAõÃAÌÍA£×AzáAQìA(öA  A
+{A	ë
+A	ÂA	A	p€A	G®A	
+žAõÃAÌÍA£×AzáAQìA(öA  A×
+A®A
+A\)A33A
+=AáHAžRA\AffA=qA{Aë
+AÂAAp€AG®A
+žAõÃAÌÍA£×AzáAQìA(öA  A×
+A®A
+A\)A33A
+=AáHAžRA\AffA=qA{Aë
+AÂAAp€AG®A
+žA õÃA ÌÍA £×A záA QìA (öA   @ô(ö@ó×
+@ó
+@ó33@òáH@ò\@ò=q@ñë
+@ñ@ñG®@ðõÂ@ð£×@ðQì@ð  @ï®@ï\)@ï
+=@îžR@îff@î{@íÂ@íp€@í
+ž@ìÌÍ@ìzá@ì(ö@ë×
+@ë
+@ë33@êáH@ê\@ê=q@éë
+@é@éG®@èõÃ@è£×@èQì@è  @ç®@ç\)@ç
+=@æžR@æff@æ{@åÂ@åp€@å
+ž@äÌÍ@äzá@ä(ö@ã×
+@ã
+@ã33@âáH@â\@â=q@áë
+@á@áG®@àõÃ@à£×@àQì@à  @Ô(ö@Ó×
+@Ó
+@Ó33@ÒáH@Ò\@Ò=q@Ñë
+@Ñ@ÑG®@ÐõÂ@Ð£×@ÐQì@Ð  @Ï®@Ï\)@Ï
+=@ÎžR@Îff@Î{@ÍÂ@Íp€@Í
+ž@ÌÌÍ@Ìzá@Ì(ö@Ë×
+@Ë
+@Ë33@ÊáH@Ê\@Ê=q@Éë
+@É@ÉG®@ÈõÃ@È£×@ÈQì@È  @Ç®@Ç\)@Ç
+=@ÆžR@Æff@Æ{@ÅÂ@Åp€@Å
+ž@ÄÌÍ@Äzá@Ä(ö@Ã×
+@Ã
+@Ã33@ÂáH@Â\@Â=q@Áë
+@Á@ÁG®@ÀõÃ@À£×@ÀQì@À  @Ž(ö@³×
+@³
+@³33@²áH@²\@²=q@±ë
+@±@±G®@°õÂ@°£×@°Qì@°  @¯®@¯\)@¯
+=@®žR@®ff@®{@­Â@­p€@­
+ž@¬ÌÍ@¬zá@¬(ö@«×
+@«
+@«33@ªáH@ª\@ª=q@©ë
+@©@©G®@šõÃ@š£×@šQì@š  @§®@§\)@§
+=@ŠžR@Šff@Š{@¥Â@¥p€@¥
+ž@€ÌÍ@€zá@€(ö@£×
+@£
+@£33@¢áH@¢\@¢=q@¡ë
+@¡@¡G®@ õÃ@ £×@ Qì@   @(ö@×
+@
+@33@áH@\@=q@ë
+@@G®@õÂ@£×@Qì@  @®@\)@
+=@žR@ff@{@Â@p€@
+ž@ÌÍ@zá@(ö@×
+@
+@33@áH@\@=q@ë
+@@G®@õÃ@£×@Qì@  @®@\)@
+=@žR@ff@{@
+Â@
+p€@
+
+ž@ÌÍ@zá@(ö@×
+@
+@33@áH@\@=q@ë
+@@G®@õÃ@£×@Qì@  @hQì@g®@g
+>@fff@eÂ@e
+ž@dzá@c×
+@c33@b\@aë
+@aG®@`£×@`  @_\)@^žR@^{@]p€@\ÌÍ@\(ö@[
+@ZáH@Z=q@Y@XõÂ@XQì@W®@W
+>@Vff@UÂ@U
+ž@Tzá@S×
+@S33@R\@Që
+@QG®@P£×@P  @O\)@NžR@N{@Mp€@LÌÍ@L(ö@K
+@JáH@J=q@I@HõÃ@HQì@G®@G
+=@Fff@EÂ@E
+ž@Dzá@C×
+@C33@B\@Aë
+@AG®@@£×@@  @(Qì@'®@'
+>@&ff@%Â@%
+ž@$zá@#×
+@#33@"\@!ë
+@!G®@ £×@   @\)@
+žR@
+{@
+p€@
+ÌÍ@
+(ö@
+@áH@=q@@õÂ@Qì@®@
+>@ff@Â@
+ž@zá@×
+@33@\@ë
+@G®@£×@  @\)@žR@{@
+p€@
+ÌÍ@
+(ö@
+
+@
+áH@
+=q@	@õÃ@Qì@®@
+=@ff@Â@
+ž@zá@×
+@33@\@ë
+@G®@ £×@   ?Ð£×?Ï\)?Î{?ÌÌÍ?Ë
+
+?Ê=p?ÈõÂ?Ç®?Æff?Å
+ž?Ã×
+?Â\?ÁG®?À  ?ŸžR?œp€?Œ(ö?ºáH?¹?žQì?·
+>?µÂ?Žzá?³33?±ë
+?°£×?¯\)?®{?¬ÌÍ?«
+?ª=q?šõÂ?§®?Šff?¥
+ž?£×
+?¢\?¡G®?   ?žR?p€?(ö?áH??Qì?
+>?Â?zá?33?ë
+?£×?\)?{?ÌÍ?
+?=q?õÃ?®?ff?
+
+ž?×
+?\?G®?  ?!G®?
+žR?
+(ö??
+=?zá?ë
+?\)?
+ÌÍ?
+=q?®?
+ž?\?   >úáH>õÂ>ð£×>ë
+>æff>áG®>Ü(ö>×
+=>Ñë
+>ÌÌÍ>Ç®>Â\>œp€>žQì>³33>®{>šõÃ>£×
+>žR>>zá>\)>=q>
+
+ž>  >uÂ>k
+>aG®>W
+=>LÌÍ>B\>8Qì>.{>#×
+>>\)>
+ž=õÂ=áG®=ÌÌÍ=žQì=£×
+=\)=uÂ=LÌÍ=#×
+<õÂ<£×
+<#×
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
Index: /branches/rel3/psLib/test/image/verified/sBiOut.fits
===================================================================
--- /branches/rel3/psLib/test/image/verified/sBiOut.fits	(revision 2163)
+++ /branches/rel3/psLib/test/image/verified/sBiOut.fits	(revision 2163)
@@ -0,0 +1,1414 @@
+SIMPLE  =                    T / file does conform to FITS standard             BITPIX  =                   16 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   64 / length of data axis 1                          NAXIS2  =                   64 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          EXTEND  =                    T / FITS dataset may contain extensions            COMMENT   FITS (Flexible Image Transport System) format is defined in 'AstronomyCOMMENT   and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - / 1 3 5 7 9 ; = ?ÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , . 0 2 4 6 8 : < >ÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - / 1 3 5 7 9 ; =ÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , . 0 2 4 6 8 : <ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - / 1 3 5 7 9 ;ÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , . 0 2 4 6 8 :ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - / 1 3 5 7 9ÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , . 0 2 4 6 8ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - / 1 3 5 7ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , . 0 2 4 6ÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - / 1 3 5ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , . 0 2 4ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - / 1 3ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , . 0 2ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - / 1ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , . 0ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - /ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , .ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + -ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * ,ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) +ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( *ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' )ÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & (ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % 'ÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ &ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # %ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! #ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   "ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  !ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+  ÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+ ÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+ÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+ÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+       ÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+       ÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+      ÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+      ÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+     ÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+     ÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+    ÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+    ÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+   ÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+   ÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+  ÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+  ÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+ ÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+ ÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+ÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+ÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	ÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ      ÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ    ÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ     ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ    ÿ
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ   ÿÿ
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ                                                                                                                                                                                                                                                                                                                                                                                                                                                                  XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                   16 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   91 / length of data axis 1                          NAXIS2  =                   91 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁÿÂÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÿÁÿÃÿÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿ¿ÿÂÿÄÿÆÿÇÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœÿŸÿÀÿÂÿÄÿÆÿÉÿÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŒÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿºÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹ÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿžÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¶ÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ°ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿæÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ®ÿ®ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿéÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬ÿ­ÿ¯ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ©ÿªÿ¬ÿ®ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿšÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ§ÿ§ÿ©ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥ÿŠÿšÿªÿ¬ÿ®ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢ÿ£ÿ¥ÿ§ÿ©ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ ÿ¢ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ     ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ      ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+ 
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+     ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+      ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+       ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+        
+ 
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+  !ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+       
+ 
+   " $ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+        
+  ! # % &ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+  ! $ & ( )ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+       
+ 
+   " $ & ( + ,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+        
+  ! # % ' ) + - /ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+  ! $ & ( * , . 0 2ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+       
+ 
+   " $ & ( + - / 1 3 5ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+        
+  ! # % ' ) + - 0 2 4 6 7ÿÿÿÿÿÿÿÿÿ
+ÿ
+ÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+  ! $ & ( * , . 0 2 4 7 9 :ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+       
+ 
+   " $ & ( + - / 1 3 5 7 9 < =ÿÿÿ
+ÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+        
+  ! # % ' ) + - 0 2 4 6 8 : < >ÿÿÿÿ
+ÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+  ! $ & ( * , . 0 2 4 7 9 ; = >ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+       
+ 
+   " $ & ( + - / 1 3 5 7 9 < <ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+        
+  ! # % ' ) + - 0 2 4 6 8 : ;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+  ! $ & ( * , . 0 2 4 7 9 :ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+       
+ 
+   " $ & ( + - / 1 3 5 7 8ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+        
+  ! # % ' ) + - 0 2 4 6 7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+  ! $ & ( * , . 0 2 4 5ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+       
+ 
+   " $ & ( + - / 1 3 4ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+        
+  ! # % ' ) + - 0 2 2ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+  ! $ & ( * , . 0 1ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+       
+ 
+   " $ & ( + - / 0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+        
+  ! # % ' ) + - .ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŠÿ§ÿ©ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+  ! $ & ( * , -ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ©ÿªÿ¬ÿ®ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+       
+ 
+   " $ & ( + +ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬ÿ­ÿ¯ÿ±ÿ³ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+        
+  ! # % ' ) *ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+  ! $ & ( )ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+       
+ 
+   " $ & 'ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+        
+  ! # % &ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ·ÿžÿºÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+  ! $ $ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿºÿ»ÿœÿ¿ÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+       
+ 
+   " #ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœÿŸÿÀÿÂÿÄÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+        
+  ! !ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+       
+ 
+ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅÿÆÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+        
+ 
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÈÿÉÿËÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËÿÌÿÎÿÐÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+       ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÎÿÏÿÑÿÓÿÕÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+       ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐÿÒÿÔÿÖÿØÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+      ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+     ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖÿ×ÿÚÿÜÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+     ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙÿÚÿÜÿßÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜÿÝÿßÿáÿãÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞÿàÿâÿäÿæÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿáÿãÿåÿçÿéÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäÿæÿèÿêÿìÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 
+ 
+ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿçÿèÿëÿíÿïÿñÿóÿõÿ÷ÿùÿüÿþ       	 
+ 
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿêÿëÿíÿïÿòÿôÿöÿøÿúÿüÿþ       
+ 
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíÿîÿðÿòÿôÿ÷ÿùÿûÿýÿÿ      	 	ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿñÿóÿõÿ÷ÿùÿüÿþ       ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòÿôÿöÿøÿúÿüÿþ      ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõÿ÷ÿùÿûÿýÿÿ     ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿùÿüÿþ     ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûÿüÿþ    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿ   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                   16 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   64 / length of data axis 1                          NAXIS2  =                   64 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ÿÿÿÿ
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¡ÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÿ
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¡ÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¡ÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¡ÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¡ÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¡ÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¡ÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¡ÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¡ÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¡ÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÿÿÿÿÿÿÿÿÿÿ ÿ¡ÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÿÿÿÿÿÿÿÿ ÿ¡ÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿÿÿÿÿÿÿ ÿ¡ÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÿÿÿÿ ÿ¡ÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÿÿ ÿ¡ÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿ ÿ¡ÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿ¢ÿ£ÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿ€ÿ¥ÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿŠÿ§ÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿšÿ©ÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿªÿ«ÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿ¬ÿ­ÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿ®ÿ¯ÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿ°ÿ±ÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿ²ÿ³ÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿŽÿµÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿ¶ÿ·ÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿžÿ¹ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿºÿ»ÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿŒÿœÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿŸÿ¿ÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿÀÿÁÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿÿÂÿÃÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ   ÿÄÿÅÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ     ÿÆÿÇÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ       ÿÈÿÉÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ         ÿÊÿËÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	ÿÌÿÍÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ÿÎÿÏÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+ÿÐÿÑÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+  ÿÒÿÓÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+    ÿÔÿÕÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+      ÿÖÿ×ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+        ÿØÿÙÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+          ÿÚÿÛÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+            ÿÜÿÝÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+              ÿÞÿßÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ÿàÿáÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ 
+ ÿâÿãÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ 
+    !ÿäÿåÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ 
+    ! " #ÿæÿçÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ 
+    ! " # $ %ÿèÿéÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ 
+    ! " # $ % & 'ÿêÿëÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ 
+    ! " # $ % & ' ( )ÿìÿíÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ 
+    ! " # $ % & ' ( ) * +ÿîÿïÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ 
+    ! " # $ % & ' ( ) * + , -ÿðÿñÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ 
+    ! " # $ % & ' ( ) * + , - . /ÿòÿóÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ 
+    ! " # $ % & ' ( ) * + , - . / 0 1ÿôÿõÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ 
+    ! " # $ % & ' ( ) * + , - . / 0 1 2 3ÿöÿ÷ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ 
+    ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5ÿøÿùÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ 
+    ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7ÿúÿûÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ 
+    ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9ÿüÿýÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ 
+    ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ;ÿþÿÿ           	 
+ 
+ 
+ 
+               
+ 
+ 
+    ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < =           	 
+ 
+ 
+ 
+               
+ 
+ 
+    ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?                                                                                                                                                                                                                                                                                                                                                                                                                                                                XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                   16 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   91 / length of data axis 1                          NAXIS2  =                   91 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
+ÿ
+ÿ
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢ÿ ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥ÿ£ÿ¢ÿ¢ÿ¡ÿ ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ§ÿŠÿ¥ÿ¥ÿ€ÿ£ÿ¢ÿ¢ÿ¡ÿ ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿªÿ©ÿšÿ§ÿ§ÿŠÿ¥ÿ¥ÿ€ÿ£ÿ¢ÿ¢ÿ¡ÿ ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ­ÿ¬ÿ«ÿªÿ©ÿ©ÿšÿ§ÿ§ÿŠÿ¥ÿ¥ÿ€ÿ£ÿ¢ÿ¢ÿ¡ÿ ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ°ÿ®ÿ®ÿ­ÿ¬ÿ¬ÿ«ÿªÿ©ÿ©ÿšÿ§ÿ§ÿŠÿ¥ÿ¥ÿ€ÿ£ÿ¢ÿ¢ÿ¡ÿ ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³ÿ±ÿ±ÿ°ÿ¯ÿ®ÿ®ÿ­ÿ¬ÿ¬ÿ«ÿªÿ©ÿ©ÿšÿ§ÿ§ÿŠÿ¥ÿ¥ÿ€ÿ£ÿ¢ÿ¢ÿ¡ÿ ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµÿŽÿ³ÿ³ÿ²ÿ±ÿ±ÿ°ÿ¯ÿ®ÿ®ÿ­ÿ¬ÿ¬ÿ«ÿªÿ©ÿ©ÿšÿ§ÿ§ÿŠÿ¥ÿ¥ÿ€ÿ£ÿ¢ÿ¢ÿ¡ÿ ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿ³ÿ²ÿ±ÿ±ÿ°ÿ¯ÿ®ÿ®ÿ­ÿ¬ÿ¬ÿ«ÿªÿ©ÿ©ÿšÿ§ÿ§ÿŠÿ¥ÿ¥ÿ€ÿ£ÿ¢ÿ¢ÿ¡ÿ ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ»ÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿ³ÿ²ÿ±ÿ±ÿ°ÿ¯ÿ®ÿ®ÿ­ÿ¬ÿ¬ÿ«ÿªÿ©ÿ©ÿšÿ§ÿ§ÿŠÿ¥ÿ¥ÿ€ÿ£ÿ¢ÿ¢ÿ¡ÿ ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿ³ÿ²ÿ±ÿ±ÿ°ÿ¯ÿ®ÿ®ÿ­ÿ¬ÿ¬ÿ«ÿªÿ©ÿ©ÿšÿ§ÿ§ÿŠÿ¥ÿ¥ÿ€ÿ£ÿ¢ÿ¢ÿ¡ÿ ÿ ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿ³ÿ²ÿ±ÿ±ÿ°ÿ¯ÿ®ÿ®ÿ­ÿ¬ÿ¬ÿ«ÿªÿ©ÿ©ÿšÿ§ÿ§ÿŠÿ¥ÿ¥ÿ€ÿ£ÿ¢ÿ¢ÿ¡ÿ¢ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿ³ÿ²ÿ±ÿ±ÿ°ÿ¯ÿ®ÿ®ÿ­ÿ¬ÿ¬ÿ«ÿªÿ©ÿ©ÿšÿ§ÿ§ÿŠÿ¥ÿ¥ÿ€ÿ£ÿ¢ÿ£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿ³ÿ²ÿ±ÿ±ÿ°ÿ¯ÿ®ÿ®ÿ­ÿ¬ÿ¬ÿ«ÿªÿ©ÿ©ÿšÿ§ÿ§ÿŠÿ¥ÿ¥ÿ€ÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿ³ÿ²ÿ±ÿ±ÿ°ÿ¯ÿ®ÿ®ÿ­ÿ¬ÿ¬ÿ«ÿªÿ©ÿ©ÿšÿ§ÿ§ÿŠÿ¥ÿŠÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿ³ÿ²ÿ±ÿ±ÿ°ÿ¯ÿ®ÿ®ÿ­ÿ¬ÿ¬ÿ«ÿªÿ©ÿ©ÿšÿ§ÿ§ÿ§ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿ³ÿ²ÿ±ÿ±ÿ°ÿ¯ÿ®ÿ®ÿ­ÿ¬ÿ¬ÿ«ÿªÿ©ÿ©ÿšÿ©ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿ³ÿ²ÿ±ÿ±ÿ°ÿ¯ÿ®ÿ®ÿ­ÿ¬ÿ¬ÿ«ÿªÿ©ÿªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿ³ÿ²ÿ±ÿ±ÿ°ÿ¯ÿ®ÿ®ÿ­ÿ¬ÿ¬ÿ«ÿ¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿ³ÿ²ÿ±ÿ±ÿ°ÿ¯ÿ®ÿ®ÿ­ÿ¬ÿ­ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿ³ÿ²ÿ±ÿ±ÿ°ÿ¯ÿ®ÿ®ÿ®ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿ³ÿ²ÿ±ÿ±ÿ°ÿ¯ÿ°ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿ³ÿ²ÿ±ÿ±ÿ±ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿãÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿ³ÿ²ÿ³ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿŽÿ³ÿŽÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ¶ÿµÿµÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿ·ÿ¶ÿ·ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿžÿžÿžÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿºÿ¹ÿºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿ»ÿºÿ»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿœÿŒÿœÿÿÿÿÿÿÿÿÿÿÿÿÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿŸÿœÿŸÿÿÿÿÿÿÿÿÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿ¿ÿ¿ÿ¿ÿÿÿÿÿÿÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÁÿÀÿÁ      ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÄÿÃÿÂÿÂÿÿ         ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÆÿÅÿÄÿÃÿÿÿÿ          ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÉÿÈÿÇÿÆÿÿÿÿÿÿÿÿ            ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿÌÿËÿËÿÊÿÉÿÿÿÿÿÿÿÿÿÿÿÿ              ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÏÿÎÿÎÿÍÿËÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ                ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÒÿÑÿÐÿÐÿÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ                  ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÕÿÔÿÓÿÓÿÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 	 	 	                 ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿ×ÿÖÿÕÿÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
+ 
+ 
+ 	 	                 ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÚÿÙÿØÿ×ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
+ 
+ 
+ 
+ 
+ 	 	                 ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÝÿÜÿÜÿÛÿÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
+  
+ 
+ 
+ 
+ 
+ 	 	                 ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿàÿßÿßÿÞÿÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ     
+ 
+ 
+ 
+ 
+ 	 	                 ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿãÿâÿáÿáÿßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ       
+ 
+ 
+ 
+ 
+ 	 	                 ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿæÿåÿäÿãÿâÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ         
+ 
+ 
+ 
+ 
+ 	 	                 ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿèÿçÿæÿåÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ           
+ 
+ 
+ 
+ 
+ 	 	                 ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿëÿêÿéÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ             
+ 
+ 
+ 
+ 
+ 	 	                 ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿîÿíÿíÿìÿëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ               
+ 
+ 
+ 
+ 
+ 	 	                 ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿñÿðÿïÿïÿíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ                 
+ 
+ 
+ 
+ 
+ 	 	                 ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿôÿóÿòÿòÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ                   
+ 
+ 
+ 
+ 
+ 	 	                 ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿ÷ÿöÿõÿôÿóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ                     
+ 
+ 
+ 
+ 
+ 	 	                 ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿùÿøÿ÷ÿöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  
+                     
+ 
+ 
+ 
+ 
+ 	 	                 ÿÿÿþÿþÿýÿüÿüÿûÿúÿùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
+ 
+ 
+ 
+                     
+ 
+ 
+ 
+ 
+ 	 	                 ÿÿÿþÿþÿýÿüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
+  
+ 
+ 
+ 
+                     
+ 
+ 
+ 
+ 
+ 	 	                 ÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ      
+ 
+ 
+ 
+                     
+ 
+ 
+ 
+ 
+ 	 	            ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ! ! !     
+ 
+ 
+ 
+                     
+ 
+ 
+ 
+ 
+ 	 	       ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ " # " ! !     
+ 
+ 
+ 
+                     
+ 
+ 
+ 
+ 
+ 	 	   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ $ $ $ # " ! !     
+ 
+ 
+ 
+                     
+ 
+ 
+ 
+ 
+ 	ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ % & % $ $ # " ! !     
+ 
+ 
+ 
+                     
+ 
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ & ' & & % $ $ # " ! !     
+ 
+ 
+ 
+                  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ( ( ( ' & & % $ $ # " ! !     
+ 
+ 
+ 
+              ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ) * ) ( ( ' & & % $ $ # " ! !     
+ 
+ 
+ 
+          ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ + + + * ) ( ( ' & & % $ $ # " ! !     
+ 
+ 
+ 
+      ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ , - , + + * ) ( ( ' & & % $ $ # " ! !     
+ 
+ 
+ 
+  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ - . - - , + + * ) ( ( ' & & % $ $ # " ! !     
+ 
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ / 0 / . - - , + + * ) ( ( ' & & % $ $ # " ! ! ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 0 1 0 0 / . - - , + + * ) ( ( ' & & % $ $ "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 2 2 2 1 0 0 / . - - , + + * ) ( ( ' & %ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 3 4 3 2 2 1 0 0 / . - - , + + * ) (ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 5 5 4 4 3 2 2 1 0 0 / . - - , +ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 6 7 6 5 4 4 3 2 2 1 0 0 / -ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 7 8 7 7 6 5 4 4 3 2 2 0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 9 9 9 8 7 7 6 5 4 3ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ : ; : 9 9 8 7 6ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ < < < ; : 9ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ = > = <ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ > >ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                   16 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   64 / length of data axis 1                          NAXIS2  =                   64 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
+ÿ   ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
+    ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿ   ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿ     ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿ    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿ      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿÿ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿ 
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿ 
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿ  
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿ  
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿ   
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿ   
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿ    
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿ    
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿ     
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿ     
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿ      
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿ      
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿ       
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿ       
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿ        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿ        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿ 
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿ 
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ   
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿ¡   
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ !  
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ "   
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠÿ€ # !  
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ $ "   
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿšÿŠ % # !  
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ & $ "   
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿªÿš ' % # !  
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ«ÿ© ( & $ "   
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿª ) ' % # !  
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ÿ« * ( & $ "   
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ + ) ' % # !  
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ÿ­ , * ( & $ "   
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ°ÿ® - + ) ' % # !  
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ¯ . , * ( & $ "   
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ²ÿ° / - + ) ' % # !  
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ± 0 . , * ( & $ "   
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿ² 1 / - + ) ' % # !  
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ 2 0 . , * ( & $ "   
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽ 3 1 / - + ) ' % # !  
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ·ÿµ 4 2 0 . , * ( & $ "   
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ 5 3 1 / - + ) ' % # !  
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ÿ· 6 4 2 0 . , * ( & $ "   
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿºÿž 7 5 3 1 / - + ) ' % # !  
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ»ÿ¹ 8 6 4 2 0 . , * ( & $ "   
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒÿº 9 7 5 3 1 / - + ) ' % # !  
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿ» : 8 6 4 2 0 . , * ( & $ "   
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸÿŒ ; 9 7 5 3 1 / - + ) ' % # !  
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœ < : 8 6 4 2 0 . , * ( & $ "   
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀÿŸ = ; 9 7 5 3 1 / - + ) ' % # !  
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ > < : 8 6 4 2 0 . , * ( & $ "   
+ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿðÿîÿìÿêÿèÿæÿäÿâÿàÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÀ ? = ; 9 7 5 3 1 / - + ) ' % # !  
+        
+ 
+ 	    ÿÿÿýÿûÿùÿ÷ÿõÿóÿñÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÇÿÅÿÃÿÁ                                                                                                                                                                                                                                                                                                                                                                                                                                                                XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                   16 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   91 / length of data axis 1                          NAXIS2  =                   91 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ   ÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ    ÿþÿüÿûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ     ÿþÿüÿùÿøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ     ÿÿÿýÿûÿùÿ÷ÿõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ      ÿþÿüÿúÿøÿöÿôÿòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ       ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 	 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿêÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
+ 
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ   
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ    
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ    
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ     
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ      
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ      
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ       
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ        
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ        
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿËÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÈÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
+ 
+        
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÅÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  
+ 
+       
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ    
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ! !  
+        
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿœÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ # "   
+ 
+       
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ $ $ !  
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ·ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ & % # !  
+        
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿŽÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ' & $ "   
+ 
+       
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ) ( & $ !  
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ * ) ' % # !  
+        
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ¯ÿ­ÿ¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ + + ( & $ "   
+ 
+       
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ®ÿ¬ÿªÿ©ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ - , * ( & $ !  
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿ©ÿ§ÿŠÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ . - + ) ' % # !  
+        
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 0 / - + ( & $ "   
+ 
+       
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 1 0 . , * ( & $ !  
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 2 2 0 - + ) ' % # !  
+        
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 4 3 1 / - + ( & $ "   
+ 
+       
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 5 4 2 0 . , * ( & $ !  
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 7 6 4 2 0 - + ) ' % # !  
+        
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 8 7 5 3 1 / - + ( & $ "   
+ 
+       
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ : 9 7 4 2 0 . , * ( & $ !  
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ; : 8 6 4 2 0 - + ) ' % # !  
+        
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ < < 9 7 5 3 1 / - + ( & $ "   
+ 
+       
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ > = ; 9 7 4 2 0 . , * ( & $ !  
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿ
+ÿ ? > < : 8 6 4 2 0 - + ) ' % # !  
+        
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿ
+ÿÿÿ = < 9 7 5 3 1 / - + ( & $ "   
+ 
+       
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ : 9 7 4 2 0 . , * ( & $ !  
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿ
+ÿ
+ÿÿÿÿÿÿÿÿ 7 6 4 2 0 - + ) ' % # !  
+        
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 5 3 1 / - + ( & $ "   
+ 
+       
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 2 0 . , * ( & $ !  
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ / - + ) ' % # !  
+        
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ , + ( & $ "   
+ 
+       
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ) ( & $ !  
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ & % # !  
+        
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ $ "   
+ 
+       
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ !  
+        
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
+ 
+        
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ        
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ       
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ      
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ    
+ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ   
+ 
+      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
+ 
+ 	      ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
+ 	     ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ      ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿ©ÿ§ÿ¥ÿ£ÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ     ÿþÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ¢ÿ ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ   ÿÿÿýÿûÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ®ÿ¬ÿªÿšÿŠÿ€ÿ¢ÿ¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ÿþÿüÿúÿøÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿ©ÿ§ÿ¥ÿ£ÿ¢ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿüÿùÿ÷ÿõÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿ§ÿ¥ÿ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúÿùÿ÷ÿôÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ®ÿ¬ÿªÿšÿŠÿ¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ÿöÿôÿòÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿ©ÿ§ÿ§ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôÿóÿñÿïÿíÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ¯ÿ­ÿ«ÿ©ÿšÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòÿðÿîÿìÿêÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ®ÿ¬ÿªÿ©ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿïÿíÿëÿéÿçÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ®ÿ¬ÿ«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìÿëÿèÿæÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ¯ÿ­ÿ¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéÿèÿæÿãÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ±ÿ®ÿ®ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæÿåÿãÿáÿßÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ²ÿ°ÿ¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäÿâÿàÿÞÿÜÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿ³ÿ±ÿ°ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿáÿßÿÝÿÛÿÙÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿµÿ³ÿ²ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞÿÜÿÚÿØÿÖÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿ¶ÿŽÿ³ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÿÚÿ×ÿÕÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿžÿ¶ÿµÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØÿ×ÿÕÿÓÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿ¹ÿ·ÿ¶ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÿÔÿÒÿÐÿÎÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿºÿžÿžÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓÿÑÿÏÿÍÿËÿÉÿÆÿÄÿÂÿÀÿŸÿŒÿºÿ¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐÿÎÿÌÿÊÿÈÿÆÿÄÿÂÿ¿ÿœÿ»ÿºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍÿËÿÉÿÇÿÅÿÃÿÁÿ¿ÿœÿŒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊÿÉÿÆÿÄÿÂÿÀÿŸÿœÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇÿÆÿÄÿÂÿ¿ÿ¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄÿÃÿÁÿÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÂÿÁÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                   16 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   64 / length of data axis 1                          NAXIS2  =                   64 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ? > = < ; : 9 8 7 6 5 4 3 2 1 0 / . - , + * ) ( ' & % $ # " !    
+ 
+ 
+               
+ 
+ 
+ 
+ 	           = < ; : 9 8 7 6 5 4 3 2 1 0 / . - , + * ) ( ' & % $ # " !    
+ 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþ ; : 9 8 7 6 5 4 3 2 1 0 / . - , + * ) ( ' & % $ # " !    
+ 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿü 9 8 7 6 5 4 3 2 1 0 / . - , + * ) ( ' & % $ # " !    
+ 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿú 7 6 5 4 3 2 1 0 / . - , + * ) ( ' & % $ # " !    
+ 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿø 5 4 3 2 1 0 / . - , + * ) ( ' & % $ # " !    
+ 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿö 3 2 1 0 / . - , + * ) ( ' & % $ # " !    
+ 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿô 1 0 / . - , + * ) ( ' & % $ # " !    
+ 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿò / . - , + * ) ( ' & % $ # " !    
+ 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿð - , + * ) ( ' & % $ # " !    
+ 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿî + * ) ( ' & % $ # " !    
+ 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿì ) ( ' & % $ # " !    
+ 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿê ' & % $ # " !    
+ 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿè % $ # " !    
+ 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæ # " !    
+ 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿä !    
+ 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâ  
+ 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿà 
+ 
+               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞ               
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜ             
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚ           
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØ         
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖ       
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔ     
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒ   
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐ 
+ 
+ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎ 
+ 
+ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌ 	          ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊ         ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈ       ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆ     ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄ   ÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÿÿþÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿýÿüÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿûÿúÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿùÿøÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ÷ÿöÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿõÿôÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿóÿòÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿñÿðÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿïÿîÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿíÿìÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿëÿêÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿéÿèÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿçÿæÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿåÿäÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿãÿâÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿáÿàÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿßÿÞÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿ¡ÿ ÿÝÿÜÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿ¡ÿ ÿÿÿÛÿÚÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿ¡ÿ ÿÿÿÿÿÙÿØÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿ¡ÿ ÿÿÿÿÿÿÿ×ÿÖÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿ¡ÿ ÿÿÿÿÿÿÿÿÿÕÿÔÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿ¡ÿ ÿÿÿÿÿÿÿÿÿÿÿÓÿÒÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿ¡ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÑÿÐÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿ¡ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÿÎÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿ¡ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍÿÌÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿ¡ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËÿÊÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿ¡ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÿÈÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿ¡ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇÿÆÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿ¡ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅÿÄÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿ¡ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃÿÂÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿ¡ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
+ÿÿÁÿÀÿ¿ÿŸÿœÿŒÿ»ÿºÿ¹ÿžÿ·ÿ¶ÿµÿŽÿ³ÿ²ÿ±ÿ°ÿ¯ÿ®ÿ­ÿ¬ÿ«ÿªÿ©ÿšÿ§ÿŠÿ¥ÿ€ÿ£ÿ¢ÿ¡ÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
+ÿÿÿ                                                                                                                                                                                                                                                                                                                                                                                                                                                                XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                   16 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   91 / length of data axis 1                          NAXIS2  =                   91 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ > >ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ < = > =ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 9 : ; < < <ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 6 7 8 9 9 : ; :ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 3 4 5 6 7 7 8 9 9 9ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 0 2 2 3 4 4 5 6 7 7 8 7ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ - / 0 0 1 2 2 3 4 4 5 6 7 6ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ + , - - . / 0 0 1 2 2 3 4 4 5 5ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ( ) * + + , - - . / 0 0 1 2 2 3 4 3ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ % & ' ( ( ) * + + , - - . / 0 0 1 2 2 2ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ " $ $ % & & ' ( ( ) * + + , - - . / 0 0 1 0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ  ! ! " # $ $ % & & ' ( ( ) * + + , - - . / 0 /ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
+ 
+     ! ! " # $ $ % & & ' ( ( ) * + + , - - . -ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ   
+ 
+ 
+ 
+     ! ! " # $ $ % & & ' ( ( ) * + + , - ,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ       
+ 
+ 
+ 
+     ! ! " # $ $ % & & ' ( ( ) * + + +ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ           
+ 
+ 
+ 
+     ! ! " # $ $ % & & ' ( ( ) * )ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ               
+ 
+ 
+ 
+     ! ! " # $ $ % & & ' ( ( (ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ                   
+ 
+ 
+ 
+     ! ! " # $ $ % & & ' &ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 
+ 
+                     
+ 
+ 
+ 
+     ! ! " # $ $ % & %ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ 	 
+ 
+ 
+ 
+ 
+                     
+ 
+ 
+ 
+     ! ! " # $ $ $ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ    	 	 
+ 
+ 
+ 
+ 
+                     
+ 
+ 
+ 
+     ! ! " # "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ        	 	 
+ 
+ 
+ 
+ 
+                     
+ 
+ 
+ 
+     ! ! !ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ             	 	 
+ 
+ 
+ 
+ 
+                     
+ 
+ 
+ 
+     ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ                  	 	 
+ 
+ 
+ 
+ 
+                     
+ 
+ 
+ 
+  
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüÿýÿþÿþÿÿ                  	 	 
+ 
+ 
+ 
+ 
+                     
+ 
+ 
+ 
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùÿúÿûÿüÿüÿýÿþÿþÿÿ                  	 	 
+ 
+ 
+ 
+ 
+                     
+ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ                  	 	 
+ 
+ 
+ 
+ 
+                    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ                  	 	 
+ 
+ 
+ 
+ 
+                  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ                  	 	 
+ 
+ 
+ 
+ 
+                ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ                  	 	 
+ 
+ 
+ 
+ 
+              ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ                  	 	 
+ 
+ 
+ 
+ 
+            ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ                  	 	 
+ 
+ 
+ 
+ 
+          ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿåÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ                  	 	 
+ 
+ 
+ 
+ 
+        ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ                  	 	 
+ 
+ 
+ 
+ 
+      ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ                  	 	 
+ 
+ 
+ 
+ 
+    ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ                  	 	 
+ 
+ 
+ 
+ 
+  
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ                  	 	 
+ 
+ 
+ 
+ 
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ                  	 	 
+ 
+ 
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ                  	 	 	ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ                  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÎÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ                ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ              ÿÿÿÿÿÿÿÿÿÿÿÿÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ            ÿÿÿÿÿÿÿÿÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ          ÿÿÿÿÿÃÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ         ÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿþÿÿ    ÿÿÿÁÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿüÿýÿþÿÿÿÿÿÿÿ¿ÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿùÿúÿûÿüÿÿÿÿÿÿÿÿÿŸÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿöÿ÷ÿ÷ÿøÿùÿÿÿÿÿÿÿÿÿÿÿÿÿœÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿóÿôÿôÿõÿ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ»ÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿðÿñÿòÿòÿôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿºÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿíÿîÿïÿïÿñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿžÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿëÿìÿíÿîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ·ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿèÿéÿêÿëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿåÿæÿæÿçÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŽÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿâÿãÿãÿäÿæÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³ÿ²ÿ³ÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿßÿàÿáÿáÿãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ±ÿ±ÿ±ÿ²ÿ³ÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÜÿÝÿÞÿßÿàÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ°ÿ¯ÿ°ÿ±ÿ±ÿ²ÿ³ÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÚÿÛÿÜÿÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ®ÿ®ÿ®ÿ¯ÿ°ÿ±ÿ±ÿ²ÿ³ÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿ×ÿØÿÙÿÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ­ÿ¬ÿ­ÿ®ÿ®ÿ¯ÿ°ÿ±ÿ±ÿ²ÿ³ÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÔÿÕÿÕÿÖÿ×ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬ÿ«ÿ¬ÿ¬ÿ­ÿ®ÿ®ÿ¯ÿ°ÿ±ÿ±ÿ²ÿ³ÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÑÿÒÿÓÿÓÿÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿªÿ©ÿªÿ«ÿ¬ÿ¬ÿ­ÿ®ÿ®ÿ¯ÿ°ÿ±ÿ±ÿ²ÿ³ÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÎÿÏÿÐÿÐÿÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ©ÿšÿ©ÿ©ÿªÿ«ÿ¬ÿ¬ÿ­ÿ®ÿ®ÿ¯ÿ°ÿ±ÿ±ÿ²ÿ³ÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿËÿÌÿÍÿÎÿÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ§ÿ§ÿ§ÿšÿ©ÿ©ÿªÿ«ÿ¬ÿ¬ÿ­ÿ®ÿ®ÿ¯ÿ°ÿ±ÿ±ÿ²ÿ³ÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÉÿÊÿËÿÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŠÿ¥ÿŠÿ§ÿ§ÿšÿ©ÿ©ÿªÿ«ÿ¬ÿ¬ÿ­ÿ®ÿ®ÿ¯ÿ°ÿ±ÿ±ÿ²ÿ³ÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÆÿÇÿÈÿÉÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ÿ€ÿ¥ÿ¥ÿŠÿ§ÿ§ÿšÿ©ÿ©ÿªÿ«ÿ¬ÿ¬ÿ­ÿ®ÿ®ÿ¯ÿ°ÿ±ÿ±ÿ²ÿ³ÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÃÿÄÿÄÿÅÿÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ£ÿ¢ÿ£ÿ€ÿ¥ÿ¥ÿŠÿ§ÿ§ÿšÿ©ÿ©ÿªÿ«ÿ¬ÿ¬ÿ­ÿ®ÿ®ÿ¯ÿ°ÿ±ÿ±ÿ²ÿ³ÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÀÿÁÿÂÿÂÿÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢ÿ¡ÿ¢ÿ¢ÿ£ÿ€ÿ¥ÿ¥ÿŠÿ§ÿ§ÿšÿ©ÿ©ÿªÿ«ÿ¬ÿ¬ÿ­ÿ®ÿ®ÿ¯ÿ°ÿ±ÿ±ÿ²ÿ³ÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿœÿŸÿ¿ÿ¿ÿÁÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ ÿ ÿ¡ÿ¢ÿ¢ÿ£ÿ€ÿ¥ÿ¥ÿŠÿ§ÿ§ÿšÿ©ÿ©ÿªÿ«ÿ¬ÿ¬ÿ­ÿ®ÿ®ÿ¯ÿ°ÿ±ÿ±ÿ²ÿ³ÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿºÿ»ÿŒÿœÿŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ ÿ¡ÿ¢ÿ¢ÿ£ÿ€ÿ¥ÿ¥ÿŠÿ§ÿ§ÿšÿ©ÿ©ÿªÿ«ÿ¬ÿ¬ÿ­ÿ®ÿ®ÿ¯ÿ°ÿ±ÿ±ÿ²ÿ³ÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿžÿ¹ÿºÿ»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ ÿ¡ÿ¢ÿ¢ÿ£ÿ€ÿ¥ÿ¥ÿŠÿ§ÿ§ÿšÿ©ÿ©ÿªÿ«ÿ¬ÿ¬ÿ­ÿ®ÿ®ÿ¯ÿ°ÿ±ÿ±ÿ²ÿ³ÿ³ÿŽÿµÿ¶ÿ¶ÿ·ÿžÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ ÿ¡ÿ¢ÿ¢ÿ£ÿ€ÿ¥ÿ¥ÿŠÿ§ÿ§ÿšÿ©ÿ©ÿªÿ«ÿ¬ÿ¬ÿ­ÿ®ÿ®ÿ¯ÿ°ÿ±ÿ±ÿ²ÿ³ÿ³ÿŽÿµÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ ÿ¡ÿ¢ÿ¢ÿ£ÿ€ÿ¥ÿ¥ÿŠÿ§ÿ§ÿšÿ©ÿ©ÿªÿ«ÿ¬ÿ¬ÿ­ÿ®ÿ®ÿ¯ÿ°ÿ±ÿ±ÿ³ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ ÿ¡ÿ¢ÿ¢ÿ£ÿ€ÿ¥ÿ¥ÿŠÿ§ÿ§ÿšÿ©ÿ©ÿªÿ«ÿ¬ÿ¬ÿ­ÿ®ÿ®ÿ°ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ ÿ¡ÿ¢ÿ¢ÿ£ÿ€ÿ¥ÿ¥ÿŠÿ§ÿ§ÿšÿ©ÿ©ÿªÿ«ÿ¬ÿ­ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ ÿ¡ÿ¢ÿ¢ÿ£ÿ€ÿ¥ÿ¥ÿŠÿ§ÿ§ÿšÿ©ÿªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ ÿ¡ÿ¢ÿ¢ÿ£ÿ€ÿ¥ÿ¥ÿŠÿ§ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ ÿ¡ÿ¢ÿ¢ÿ£ÿ¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ ÿ¢ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
+ÿ
+ÿ
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              XTENSION= 'IMAGE   '           / IMAGE extension                                BITPIX  =                   16 / number of bits per data pixel                  NAXIS   =                    3 / number of data axes                            NAXIS1  =                   64 / length of data axis 1                          NAXIS2  =                   64 / length of data axis 2                          NAXIS3  =                    1 / length of data axis 3                          PCOUNT  =                    0 / required keyword; must = 0                     GCOUNT  =                    1 / required keyword; must = 1                     BZERO   =   0.000000000000E+00 / Pixel Value Offset                             BSCALE  =   1.000000000000E+00 / Pixel Value Scale                              END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - / 1 3 5 7 9 ; = ?ÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , . 0 2 4 6 8 : < >ÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - / 1 3 5 7 9 ; =ÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , . 0 2 4 6 8 : <ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - / 1 3 5 7 9 ;ÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , . 0 2 4 6 8 :ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - / 1 3 5 7 9ÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , . 0 2 4 6 8ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - / 1 3 5 7ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , . 0 2 4 6ÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - / 1 3 5ÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , . 0 2 4ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - / 1 3ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , . 0 2ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - / 1ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , . 0ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + - /ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * , .ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) + -ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( * ,ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' ) +ÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & ( *ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % ' )ÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ & (ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # % 'ÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ &ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! # %ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   " $ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  ! #ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+   "ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+  !ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+  ÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+ ÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ 
+ÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+        
+ÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+        
+ÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+       ÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+       ÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+      ÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+      ÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+     ÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+     ÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+    ÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+    ÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+   ÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+   ÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+  ÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+  ÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+ ÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+ ÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ 
+ÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ 
+ÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	 
+ÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ       
+ÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ     	ÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ      ÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ    ÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ     ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ    ÿ
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ   ÿÿ
+ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÿ£ÿ¥ÿ§ÿ©ÿ«ÿ­ÿ¯ÿ±ÿ³ÿµÿ·ÿ¹ÿ»ÿœÿ¿ÿÁÿÃÿÅÿÇÿÉÿËÿÍÿÏÿÑÿÓÿÕÿ×ÿÙÿÛÿÝÿßÿáÿãÿåÿçÿéÿëÿíÿïÿñÿóÿõÿ÷ÿùÿûÿýÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ¢ÿ€ÿŠÿšÿªÿ¬ÿ®ÿ°ÿ²ÿŽÿ¶ÿžÿºÿŒÿŸÿÀÿÂÿÄÿÆÿÈÿÊÿÌÿÎÿÐÿÒÿÔÿÖÿØÿÚÿÜÿÞÿàÿâÿäÿæÿèÿêÿìÿîÿðÿòÿôÿöÿøÿúÿüÿþ                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
Index: /branches/rel3/psLib/test/image/verified/tst_psImage.stderr
===================================================================
--- /branches/rel3/psLib/test/image/verified/tst_psImage.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/image/verified/tst_psImage.stderr	(revision 2163)
@@ -0,0 +1,118 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImage.c                                              *
+*            TestPoint: psImage{psImageAlloc}                                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    #546 - psImageAlloc shall allocate memory for a psImage structure
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Testing psImage with type 101h
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageAlloc
+    Specified number of rows (0) or columns (0) is invalid.
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Testing psImage with type 102h
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageAlloc
+    Specified number of rows (0) or columns (0) is invalid.
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Testing psImage with type 104h
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageAlloc
+    Specified number of rows (0) or columns (0) is invalid.
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Testing psImage with type 108h
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageAlloc
+    Specified number of rows (0) or columns (0) is invalid.
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Testing psImage with type 301h
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageAlloc
+    Specified number of rows (0) or columns (0) is invalid.
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Testing psImage with type 302h
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageAlloc
+    Specified number of rows (0) or columns (0) is invalid.
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Testing psImage with type 304h
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageAlloc
+    Specified number of rows (0) or columns (0) is invalid.
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Testing psImage with type 308h
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageAlloc
+    Specified number of rows (0) or columns (0) is invalid.
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Testing psImage with type 404h
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageAlloc
+    Specified number of rows (0) or columns (0) is invalid.
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Testing psImage with type 408h
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageAlloc
+    Specified number of rows (0) or columns (0) is invalid.
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Testing psImage with type 808h
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageAlloc
+    Specified number of rows (0) or columns (0) is invalid.
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Testing psImage with type 810h
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageAlloc
+    Specified number of rows (0) or columns (0) is invalid.
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Testing psImage with type 0h
+<DATE><TIME>|<HOST>|I|testImageAlloc
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageAlloc
+    Specified number of rows (0) or columns (0) is invalid.
+
+---> TESTPOINT PASSED (psImage{psImageAlloc} | tst_psImage.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImage.c                                              *
+*            TestPoint: psImage{psImageCopy}                                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageCopy
+    Image Copy Test for psU8
+<DATE><TIME>|<HOST>|I|testImageCopy
+    Image Copy Test for psU16
+<DATE><TIME>|<HOST>|I|testImageCopy
+    Image Copy Test for psU32
+<DATE><TIME>|<HOST>|I|testImageCopy
+    Image Copy Test for psS8
+<DATE><TIME>|<HOST>|I|testImageCopy
+    Image Copy Test for psS16
+<DATE><TIME>|<HOST>|I|testImageCopy
+    Image Copy Test for psS32
+<DATE><TIME>|<HOST>|I|testImageCopy
+    Image Copy Test for psF32
+<DATE><TIME>|<HOST>|I|testImageCopy
+    Image Copy Test for psF64
+<DATE><TIME>|<HOST>|I|testImageCopy
+    An error should follow...
+<DATE><TIME>|<HOST>|E|psLib.image.psImageCopy
+    Can not operate on a NULL psImage.
+
+---> TESTPOINT PASSED (psImage{psImageCopy} | tst_psImage.c)
+
Index: /branches/rel3/psLib/test/image/verified/tst_psImageConvolve.stderr
===================================================================
--- /branches/rel3/psLib/test/image/verified/tst_psImageConvolve.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/image/verified/tst_psImageConvolve.stderr	(revision 2163)
@@ -0,0 +1,42 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageConvolve.c                                      *
+*            TestPoint: psImage{psKernelAlloc}                                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testKernelAlloc
+    Following should be a warning (xMin > xMax)
+<DATE><TIME>|<HOST>|W|psKernelAlloc
+    Specified xMin, 5, was greater than xMax, -5.  Values swapped.
+<DATE><TIME>|<HOST>|I|testKernelAlloc
+    Following should be a warning (yMin > yMax)
+<DATE><TIME>|<HOST>|W|psKernelAlloc
+    Specified yMin, 5, was greater than yMax, -5.  Values swapped.
+
+---> TESTPOINT PASSED (psImage{psKernelAlloc} | tst_psImageConvolve.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageConvolve.c                                      *
+*            TestPoint: psImage{psKernelGenerate}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testKernelGenerate
+    Following should be a warning - not automatically tested.
+<DATE><TIME>|<HOST>|W|psKernelGenerate
+    Shift vectors found to be different sizes.
+<DATE><TIME>|<HOST>|I|testKernelGenerate
+    Following should be a error (time vector NULL).
+<DATE><TIME>|<HOST>|E|psLib.image.psKernelGenerate
+    Specified shift vectors can not be NULL.
+<DATE><TIME>|<HOST>|I|testKernelGenerate
+    Following should be a error (x vector NULL).
+<DATE><TIME>|<HOST>|E|psLib.image.psKernelGenerate
+    Specified shift vectors can not be NULL.
+<DATE><TIME>|<HOST>|I|testKernelGenerate
+    Following should be a error (y vector NULL).
+<DATE><TIME>|<HOST>|E|psLib.image.psKernelGenerate
+    Specified shift vectors can not be NULL.
+
+---> TESTPOINT PASSED (psImage{psKernelGenerate} | tst_psImageConvolve.c)
+
Index: /branches/rel3/psLib/test/image/verified/tst_psImageExtraction.stderr
===================================================================
--- /branches/rel3/psLib/test/image/verified/tst_psImageExtraction.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/image/verified/tst_psImageExtraction.stderr	(revision 2163)
@@ -0,0 +1,300 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageExtraction.c                                    *
+*            TestPoint: psImage{psImageSubset}                                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageSubset
+    Verify the returned psImage structure members nrow and ncol are equal to the input parameter nrow and ncol respectively.
+<DATE><TIME>|<HOST>|I|testImageSubset
+    Verify the returned psImage structure contains expected values in the row member, if the input psImage structure image contains known values.
+<DATE><TIME>|<HOST>|I|testImageSubset
+    Verify the returned psImage structure member type is equal to the input psImage structure member type.
+<DATE><TIME>|<HOST>|I|testImageSubset
+    Verify the returned psImage structure members row0 and col0 are equal to the input parameters row0 and col0 respectively.
+<DATE><TIME>|<HOST>|I|testImageSubset
+    Verify the returned psImage structure member parent is equal to the input psImage structure pointer image.
+<DATE><TIME>|<HOST>|I|testImageSubset
+    Verify the returned psImage structure member children is null.
+<DATE><TIME>|<HOST>|I|testImageSubset
+    Verify the input psImage structure image only has the following members changed: 1) Nchildren is increased by one. 2) parent contains pointer psImage structure out at parent[Nchildren-1].
+<DATE><TIME>|<HOST>|I|testImageSubset
+    Verify the returned psImage structure pointer is null and program execution doesn't stop, if the input parameter image is null. Also verified the input psImage structure is not modified.
+<DATE><TIME>|<HOST>|I|testImageSubset
+    An error should follow...
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubset
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageSubset
+    Verify the returned psImage structure pointer is null and program  execution doesn't stop, if the input parameters nrow and/or ncol are zero. Also verify input psImage structure is not modified.
+<DATE><TIME>|<HOST>|I|testImageSubset
+    An error should follow...
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubset
+    Specified subset range, [0:<LINENO>,128:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSubset
+    An error should follow...
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubset
+    Specified subset range, [64:<LINENO>,0:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSubset
+    Verify the returned psImage structure pointer is null and program execution doesn't stop, if the input parameters row0 and col0 are not within the range of values of psImage structure image.
+<DATE><TIME>|<HOST>|I|testImageSubset
+    An error should follow...
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubset
+    Specified subset range, [0:<LINENO>,0:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSubset
+    An error should follow...
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubset
+    Specified subset range, [0:<LINENO>,0:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSubset
+    An error should follow...
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubset
+    Specified subset range, [-1:<LINENO>,0:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSubset
+    An error should follow...
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubset
+    Specified subset range, [0:<LINENO>,-1:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSubset
+    Verify the returned psImage structure pointer is null and program execution doesn't stop if the input parameters nrow, ncol, row0 and col0 specify a range of data not within the input psImage structure image.  Also verify the input psImage structure is not modified.
+<DATE><TIME>|<HOST>|I|testImageSubset
+    An error should follow...
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubset
+    Specified subset range, [0:<LINENO>,0:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSubset
+    An error should follow...
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubset
+    Specified subset range, [0:<LINENO>,0:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSubset
+    An error should follow...
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubset
+    Specified subset range, [0:<LINENO>,0:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSubset
+    psImageFreeChildren shall deallocate any children images of a psImage structure
+
+---> TESTPOINT PASSED (psImage{psImageSubset} | tst_psImageExtraction.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageExtraction.c                                    *
+*            TestPoint: psImage{psImageSubsection}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageSubsection
+    Testing subsection [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSubsection
+    Testing subsection [32:<LINENO>,32:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSubsection
+    Testing subsection [64:<LINENO>,32:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSubsection
+    Testing subsection [32:<LINENO>,128:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSubsection
+    An error should follow (x1>x2)
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubsection
+    Specified subset range, [64:<LINENO>,32:<LINENO>], is invalid.  Ranges must be incremental.
+<DATE><TIME>|<HOST>|I|testImageSubsection
+    An error should follow (y1>y2)
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubsection
+    Specified subset range, [32:<LINENO>,64:<LINENO>], is invalid.  Ranges must be incremental.
+<DATE><TIME>|<HOST>|I|testImageSubsection
+    An error should follow (x2>nCols)
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubset
+    Specified subset range, [64:<LINENO>,32:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSubsection
+    An error should follow (y2>=nRows)
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubset
+    Specified subset range, [32:<LINENO>,64:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSubsection
+    An error should follow (malformed string - no brackets)
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubsection
+    Specified subsection string, '32:<LINENO>,32:<LINENO>', can not be parsed.  Must be in the form '[x1:x2,y1:y2]'.
+<DATE><TIME>|<HOST>|I|testImageSubsection
+    An error should follow (malformed string - no colons)
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubsection
+    Specified subsection string, '[32-64,32-64]', can not be parsed.  Must be in the form '[x1:x2,y1:y2]'.
+<DATE><TIME>|<HOST>|I|testImageSubsection
+    An error should follow (malformed string - not four numbers)
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubsection
+    Specified subsection string, '[32:<LINENO>,32]', can not be parsed.  Must be in the form '[x1:x2,y1:y2]'.
+<DATE><TIME>|<HOST>|I|testImageSubsection
+    An error should follow (image is NULL)
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubset
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageSubsection
+    An error should follow (subsection string is NULL)
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSubsection
+    Specified subsection string can not be NULL.
+
+---> TESTPOINT PASSED (psImage{psImageSubsection} | tst_psImageExtraction.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageExtraction.c                                    *
+*            TestPoint: psImage{psImageSlice}                                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageSlice
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSlice
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageSlice
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSlice
+    Specified statistic can not be NULL.
+<DATE><TIME>|<HOST>|I|testImageSlice
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSlice
+    Specified slice direction, 5, is invalid.
+<DATE><TIME>|<HOST>|I|testImageSlice
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSlice
+    Specified subset range, [30:<LINENO>,20:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSlice
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSlice
+    Specified subset range, [301:<LINENO>,20:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSlice
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSlice
+    Specified subset range, [30:<LINENO>,201:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSlice
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSlice
+    Specified subset range, [30:<LINENO>,20:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSlice
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSlice
+    Specified subset range, [30:<LINENO>,20:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageSlice
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSlice
+    Specified statistic option, 0, is not valid.  Must specify one and only one statistic type.
+<DATE><TIME>|<HOST>|I|testImageSlice
+    Following should be an error mask size != image size.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSlice
+    Input psImage mask size, 200x300, does not match psImage input size, 300x200.
+<DATE><TIME>|<HOST>|I|testImageSlice
+    Following should be an error invalid mask type.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSlice
+    Input psImage mask type, psS8, is not the supported mask datatype of psU8.
+<DATE><TIME>|<HOST>|I|testImageSlice
+    Following should be an error invalid image type.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageSlice
+    Specified psImage type, psU8, is not supported.
+
+---> TESTPOINT PASSED (psImage{psImageSlice} | tst_psImageExtraction.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageExtraction.c                                    *
+*            TestPoint: psImage{psImageTrim}                                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psLib.image.psImageTrim
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageTrim
+    Specified subset range, [-1:<LINENO>,0:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|E|psLib.image.psImageTrim
+    Specified subset range, [0:<LINENO>,-1:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|E|psLib.image.psImageTrim
+    Specified subset range, [0:<LINENO>,0:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|E|psLib.image.psImageTrim
+    Specified subset range, [0:<LINENO>,0:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|E|psLib.image.psImageTrim
+    Specified subset range, [0:-1,0:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|E|psLib.image.psImageTrim
+    Specified subset range, [0:<LINENO>,0:-1], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+
+---> TESTPOINT PASSED (psImage{psImageTrim} | tst_psImageExtraction.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageExtraction.c                                    *
+*            TestPoint: psImage{psImageCut}                                        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageCut
+    The following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageCut
+    Specified line, (-1.000000,10.000000)->(240.000000,180.000000), does not entirely lie in psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageCut
+    The following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageCut
+    Specified line, (300.000000,10.000000)->(240.000000,180.000000), does not entirely lie in psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageCut
+    The following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageCut
+    Specified line, (20.000000,10.000000)->(-1.000000,180.000000), does not entirely lie in psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageCut
+    The following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageCut
+    Specified line, (20.000000,10.000000)->(300.000000,180.000000), does not entirely lie in psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageCut
+    The following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageCut
+    Specified line, (20.000000,-1.000000)->(240.000000,180.000000), does not entirely lie in psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageCut
+    The following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageCut
+    Specified line, (20.000000,200.000000)->(240.000000,180.000000), does not entirely lie in psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageCut
+    The following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageCut
+    Specified line, (20.000000,10.000000)->(240.000000,-1.000000), does not entirely lie in psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageCut
+    The following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageCut
+    Specified line, (20.000000,10.000000)->(240.000000,200.000000), does not entirely lie in psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageCut
+    Following should be an error (NULL image).
+<DATE><TIME>|<HOST>|E|psLib.image.psImageCut
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageCut
+    Following should be an error (length=0).
+<DATE><TIME>|<HOST>|E|psLib.image.psImageCut
+    Specified number of samples, 0, must be greater than 1 to make a line.
+
+---> TESTPOINT PASSED (psImage{psImageCut} | tst_psImageExtraction.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageExtraction.c                                    *
+*            TestPoint: psImage{psImageRadialCut}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageRadialCut
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRadialCut
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageRadialCut
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRadialCut
+    Specified radii vector can not be NULL.
+<DATE><TIME>|<HOST>|I|testImageRadialCut
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRadialCut
+    Specified statistic can not be NULL.
+<DATE><TIME>|<HOST>|I|testImageRadialCut
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRadialCut
+    Specified center, (301,100), is outside of the psImage boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageRadialCut
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRadialCut
+    Specified center, (150,201), is outside of the psImage boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageRadialCut
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRadialCut
+    Input psImage mask type, psF32, is not the supported mask datatype of psU8.
+<DATE><TIME>|<HOST>|I|testImageRadialCut
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRadialCut
+    Input psImage mask size, 150x100, does not match psImage input size, 300x200.
+<DATE><TIME>|<HOST>|I|testImageRadialCut
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRadialCut
+    Input radii vector size, 1, can not be less than 2.
+<DATE><TIME>|<HOST>|I|testImageRadialCut
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRadialCut
+    Specified statistic option, 0, is not valid.  Must specify one and only one statistic type.
+
+---> TESTPOINT PASSED (psImage{psImageRadialCut} | tst_psImageExtraction.c)
+
Index: /branches/rel3/psLib/test/image/verified/tst_psImageFFT.stderr
===================================================================
--- /branches/rel3/psLib/test/image/verified/tst_psImageFFT.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/image/verified/tst_psImageFFT.stderr	(revision 2163)
@@ -0,0 +1,65 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageFFT.c                                           *
+*            TestPoint: psFFT{psImageFFT}                                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageFFT
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageFFT
+    Can not specify both PS_FFT_FORWARD and PS_FFT_REVERSE options.
+<DATE><TIME>|<HOST>|I|testImageFFT
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageFFT
+    The PS_FFT_FORWARD and PS_FFT_REAL_RESULT combinition is not supported.
+<DATE><TIME>|<HOST>|I|testImageFFT
+    Following should generate error for invalid direction.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageFFT
+    Must specify either PS_FFT_FORWARD or PS_FFT_REVERSE option.
+
+---> TESTPOINT PASSED (psFFT{psImageFFT} | tst_psImageFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageFFT.c                                           *
+*            TestPoint: psFFT{psImageRealImaginary}                                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFFT{psImageRealImaginary} | tst_psImageFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageFFT.c                                           *
+*            TestPoint: psFFT{psImageComplex}                                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageComplex
+    Following should be an error (type mismatch).
+<DATE><TIME>|<HOST>|E|psLib.image.psImageComplex
+    Real psImage type (psF32) and imaginary psImage type (psF64) must be the same.
+<DATE><TIME>|<HOST>|I|testImageComplex
+    Following should be an error (size mismatch).
+<DATE><TIME>|<HOST>|E|psLib.image.psImageComplex
+    Real psImage size (128x64) and imaginary psImage size (64x64) must be the same.
+
+---> TESTPOINT PASSED (psFFT{psImageComplex} | tst_psImageFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageFFT.c                                           *
+*            TestPoint: psFFT{psImageConjugate}                                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFFT{psImageConjugate} | tst_psImageFFT.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageFFT.c                                           *
+*            TestPoint: psFFT{psImagePowerSpectrum}                                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psFFT{psImagePowerSpectrum} | tst_psImageFFT.c)
+
Index: /branches/rel3/psLib/test/image/verified/tst_psImageIO.stderr
===================================================================
--- /branches/rel3/psLib/test/image/verified/tst_psImageIO.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/image/verified/tst_psImageIO.stderr	(revision 2163)
@@ -0,0 +1,64 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageIO.c                                            *
+*            TestPoint: psImage{psImageReadSection}                                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageRead
+    Following should be an error as file doesn't exist.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageReadSection
+    Could not open file,'foobar.fits'.
+    CFITSIO Error: could not open the named file
+<DATE><TIME>|<HOST>|I|testImageRead
+    Following should be an error as filename is NULL.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageReadSection
+    Specified filename can not be NULL.
+<DATE><TIME>|<HOST>|I|testImageRead
+    Following should be an error as extnum is invalid.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageReadSection
+    Could not find HDU #4 in file tmpImages/MxN_F32.fits.
+    CFITSIO Error: tried to move past end of file
+<DATE><TIME>|<HOST>|I|testImageRead
+    Following should be an error as extname is invalid.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageReadSection
+    Could not find HDU with extension name 'bogus' in file tmpImages/MxN_F32.fits.
+    CFITSIO Error: illegal HDU number
+
+---> TESTPOINT PASSED (psImage{psImageReadSection} | tst_psImageIO.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageIO.c                                            *
+*            TestPoint: psImage{psImageWriteSection}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageWrite
+    Following should generate an error message because input image is null.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageWriteSection
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageWrite
+    Following should be an error for passing invalid image type.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageWriteSection
+    Input psImage type, psS8, is not supported.
+<DATE><TIME>|<HOST>|I|testImageWrite
+    Following should be an error for passing invalid image type.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageWriteSection
+    Could not create file,'panstarrs/writeFits.fits'.
+    CFITSIO Error: couldn't create the named file
+<DATE><TIME>|<HOST>|I|testImageWrite
+    Following should be an error for passing invalid FITS file.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageWriteSection
+    Could not open file,'tmpImages/writeInvalidFile.fits'.
+    CFITSIO Error: tried to move past end of file
+<DATE><TIME>|<HOST>|I|testImageWrite
+    Following should be an error for invalid extension name.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageWriteSection
+    Could not find HDU with extension name 'ext2' in file tmpImages/writeTest.fits.
+    CFITSIO Error: illegal HDU number
+<DATE><TIME>|<HOST>|I|testImageWrite
+    Following should be an error for invalid extension number.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageWriteSection
+    Specified extension number, 99, must not exceed number of HDUs, 1, by more than one.
+
+---> TESTPOINT PASSED (psImage{psImageWriteSection} | tst_psImageIO.c)
+
Index: /branches/rel3/psLib/test/image/verified/tst_psImageManip.stderr
===================================================================
--- /branches/rel3/psLib/test/image/verified/tst_psImageManip.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/image/verified/tst_psImageManip.stderr	(revision 2163)
@@ -0,0 +1,323 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageManip.c                                         *
+*            TestPoint: psImage{psImageClip}                                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageClip
+    psImageClip shall limit the minimum and maximum data value within a psImage structure
+<DATE><TIME>|<HOST>|I|testImageClip
+    Testing clipping of F64 imagery
+<DATE><TIME>|<HOST>|I|testImageClip
+    Testing clipping of F32 imagery
+<DATE><TIME>|<HOST>|I|testImageClip
+    Testing clipping of S32 imagery
+<DATE><TIME>|<HOST>|I|testImageClip
+    Testing clipping of S16 imagery
+<DATE><TIME>|<HOST>|I|testImageClip
+    Testing clipping of S8 imagery
+<DATE><TIME>|<HOST>|I|testImageClip
+    Testing clipping of U16 imagery
+<DATE><TIME>|<HOST>|I|testImageClip
+    Testing clipping of U8 imagery
+<DATE><TIME>|<HOST>|I|testImageClip
+    Testing clipping of C32 imagery
+<DATE><TIME>|<HOST>|I|testImageClip
+    Testing clipping of C64 imagery
+<DATE><TIME>|<HOST>|I|testImageClip
+    Following should be an error (max<min)
+<DATE><TIME>|<HOST>|E|psLib.image.psImageClip
+    Specified min value, 256, can not be greater than the specified max value, 128.
+<DATE><TIME>|<HOST>|I|testImageClip
+    Following should be an error (invalid type)
+<DATE><TIME>|<HOST>|E|psLib.image.psImageClip
+    Specified psImage type, psU32, is not supported.
+
+---> TESTPOINT PASSED (psImage{psImageClip} | tst_psImageManip.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageManip.c                                         *
+*            TestPoint: psImage{psImageClipNAN}                                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageClipNAN
+    psImageClipNaN shall modified pixel values of NaN with a specified value
+<DATE><TIME>|<HOST>|I|testImageClipNAN
+    Following should be an error (invalid type)
+<DATE><TIME>|<HOST>|E|psLib.image.psImageClipNaN
+    Specified psImage type, psS32, is not supported.
+
+---> TESTPOINT PASSED (psImage{psImageClipNAN} | tst_psImageManip.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageManip.c                                         *
+*            TestPoint: psImage{psImageClipComplexRegion}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    psImageClipNaN shall modified pixel values of NaN with a specified value
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    Testing clipping at 409.6+256i to 682.667+512i for psC32
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    Testing clipping at 409.6+256i to 682.667+512i for psC64
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    Following should be an error:
+<DATE><TIME>|<HOST>|E|psLib.image.psImageClipComplexRegion
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    Following should be an error:
+<DATE><TIME>|<HOST>|E|psLib.image.psImageClipComplexRegion
+    Specified real-portion of min value, 10, can not be greater than the real-portion of max value, 5.
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    Following should be an error:
+<DATE><TIME>|<HOST>|E|psLib.image.psImageClipComplexRegion
+    Specified imaginary-portion of min value, 10, can not be greater than the imaginary-portion of max value, 5.
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    Following should be an error:
+<DATE><TIME>|<HOST>|E|psLib.image.psImageClipComplexRegion
+    Specified real-portion of min value, 10, can not be greater than the real-portion of max value, 5.
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    Following should be an error:
+<DATE><TIME>|<HOST>|E|psLib.image.psImageClipComplexRegion
+    Specified vmin value, -6.80565e+38+0i, is not the the range of input psImage's valid pixel values (psC32), i.e. [-3.40282e+38:<LINENO>.40282e+38].  
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    Following should be an error:
+<DATE><TIME>|<HOST>|E|psLib.image.psImageClipComplexRegion
+    Specified vmin value, 6.80565e+38+0i, is not the the range of input psImage's valid pixel values (psC32), i.e. [-3.40282e+38:<LINENO>.40282e+38].  
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    Following should be an error:
+<DATE><TIME>|<HOST>|E|psLib.image.psImageClipComplexRegion
+    Specified vmin value, -0-6.80565e+38i, is not the the range of input psImage's valid pixel values (psC32), i.e. [-3.40282e+38:<LINENO>.40282e+38].  
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    Following should be an error:
+<DATE><TIME>|<HOST>|E|psLib.image.psImageClipComplexRegion
+    Specified vmin value, 0+6.80565e+38i, is not the the range of input psImage's valid pixel values (psC32), i.e. [-3.40282e+38:<LINENO>.40282e+38].  
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    Following should be an error:
+<DATE><TIME>|<HOST>|E|psLib.image.psImageClipComplexRegion
+    Specified vmax value, -6.80565e+38+0i, is not the the range of input psImage's valid pixel values (psC32), i.e. [-3.40282e+38:<LINENO>.40282e+38].  
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    Following should be an error:
+<DATE><TIME>|<HOST>|E|psLib.image.psImageClipComplexRegion
+    Specified vmax value, 6.80565e+38+0i, is not the the range of input psImage's valid pixel values (psC32), i.e. [-3.40282e+38:<LINENO>.40282e+38].  
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    Following should be an error:
+<DATE><TIME>|<HOST>|E|psLib.image.psImageClipComplexRegion
+    Specified vmax value, -0-6.80565e+38i, is not the the range of input psImage's valid pixel values (psC32), i.e. [-3.40282e+38:<LINENO>.40282e+38].  
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    Following should be an error:
+<DATE><TIME>|<HOST>|E|psLib.image.psImageClipComplexRegion
+    Specified vmax value, 0+6.80565e+38i, is not the the range of input psImage's valid pixel values (psC32), i.e. [-3.40282e+38:<LINENO>.40282e+38].  
+<DATE><TIME>|<HOST>|I|testImageClipComplexRegion
+    Following should be an error (invalid type)
+<DATE><TIME>|<HOST>|E|psLib.image.psImageClipComplexRegion
+    Specified psImage type, psS32, is not supported.
+
+---> TESTPOINT PASSED (psImage{psImageClipComplexRegion} | tst_psImageManip.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageManip.c                                         *
+*            TestPoint: psImage{psImageOverlay}                                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageOverlay
+    Following should error as overlay isn't within image boundaries
+<DATE><TIME>|<HOST>|E|psLib.image.psImageOverlaySection
+    Specified subset range, [32:<LINENO>,64:<LINENO>], is invalid or outside input psImage's boundaries, [0:<LINENO>,0:<LINENO>].
+<DATE><TIME>|<HOST>|I|testImageOverlay
+    Following should error as overlay is NULL
+<DATE><TIME>|<HOST>|E|psLib.image.psImageOverlaySection
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageOverlay
+    Following should error as image input is NULL
+<DATE><TIME>|<HOST>|E|psLib.image.psImageOverlaySection
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageOverlay
+    Following should error as operator is invalid
+<DATE><TIME>|<HOST>|E|psLib.image.psImageOverlaySection
+    Specified operation, '$', is not supported.
+<DATE><TIME>|<HOST>|I|testImageOverlay
+    Following should error as operator is invalid
+<DATE><TIME>|<HOST>|E|psLib.image.psImageOverlaySection
+    Operation can not be NULL.
+<DATE><TIME>|<HOST>|I|testImageOverlay
+    Following should error as overlay is a different type
+<DATE><TIME>|<HOST>|E|psLib.image.psImageOverlaySection
+    Input overlay psImage type, psS64, must match input psImage type, psF32.
+<DATE><TIME>|<HOST>|I|testImageOverlay
+    Following should error as overlay and image are not valid for the psImageOverlaySection function.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageOverlaySection
+    Specified psImage type, psS64, is not supported.
+
+---> TESTPOINT PASSED (psImage{psImageOverlay} | tst_psImageManip.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageManip.c                                         *
+*            TestPoint: psImage{psImageRebin}                                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageRebin
+    Following should be an error for unsupported type.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRebin
+    Specified psImage type, psU8, is not supported.
+<DATE><TIME>|<HOST>|I|testImageRebin
+    Following should be an error for invallid mask type.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRebin
+    Input psImage mask type, psF32, is not the supported mask datatype of psU8.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRebin
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageRebin
+    Following should be an error for scale < 0.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRebin
+    Specified scale value, 0, must be a positive value.
+<DATE><TIME>|<HOST>|I|testImageRebin
+    Following should be an error for stats null.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRebin
+    Specified statistic can not be NULL.
+<DATE><TIME>|<HOST>|I|testImageRebin
+    Following should be an error for stats options 0.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRebin
+    Specified statistic option, 0, is not valid.  Must specify one and only one statistic type.
+<DATE><TIME>|<HOST>|I|testImageRebin
+    Following should be an error for stat options use range.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRebin
+    Specified statistic option, 8192, is not valid.  Must specify one and only one statistic type.
+<DATE><TIME>|<HOST>|I|testImageRebin
+    Following should be an error for stats with multiple options.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRebin
+    Specified statistic option, 2049, is not valid.  Must specify one and only one statistic type.
+
+---> TESTPOINT PASSED (psImage{psImageRebin} | tst_psImageManip.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageManip.c                                         *
+*            TestPoint: psImage{psImageRoll}                                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageRoll
+    Following should generate an error.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRoll
+    Can not operate on a NULL psImage.
+
+---> TESTPOINT PASSED (psImage{psImageRoll} | tst_psImageManip.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageManip.c                                         *
+*            TestPoint: psImage{psImageRotate}                                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageRotate
+    Following should be an error invalid type for rotate.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRotate
+    Specified psImage type, psS32, is not supported.
+<DATE><TIME>|<HOST>|I|testImageRotate
+    Following should be an error invalid type for rotate.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRotate
+    Specified psImage type, psS32, is not supported.
+<DATE><TIME>|<HOST>|I|testImageRotate
+    Following should be an error invalid type for rotate.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRotate
+    Specified psImage type, psS32, is not supported.
+<DATE><TIME>|<HOST>|I|testImageRotate
+    Following should be an error invalid type for rotate.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRotate
+    Specified psImage type, psS32, is not supported.
+<DATE><TIME>|<HOST>|I|testImageRotate
+    Following should be an error invalid type for rotate.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRotate
+    Specified psImage type, psS32, is not supported.
+<DATE><TIME>|<HOST>|I|testImageRotate
+    Following should be an error invalid type for rotate.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRotate
+    Specified psImage type, psS32, is not supported.
+<DATE><TIME>|<HOST>|I|testImageRotate
+    Following should be an error invalid type for rotate.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRotate
+    Specified psImage type, psS32, is not supported.
+<DATE><TIME>|<HOST>|I|testImageRotate
+    Following should be an error invalid type for rotate.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRotate
+    Specified psImage type, psS32, is not supported.
+<DATE><TIME>|<HOST>|I|testImageRotate
+    Following should be an error
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRotate
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageRotate
+    Following should be an error for invalid interpolation type.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageRotate
+    Specified interpolation mode, -1, is unsupported.
+
+---> TESTPOINT PASSED (psImage{psImageRotate} | tst_psImageManip.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageManip.c                                         *
+*            TestPoint: psImage{psImageShift}                                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of 0,0.
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of 0,16.
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of 0,-16.
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of 32,0.
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of -32,0.
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of 32,16.
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of 32,-16.
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of -32,16.
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of -32,-16.
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of 0,16.4.
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of 0,-16.4.
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of 32.7,0.
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of -32.7,0.
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of 32.6,16.2.
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of 32.6,-16.2.
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of -32.6,16.2.
+<DATE><TIME>|<HOST>|I|testImageShiftCase
+    Testing psImageShift with a 64x128 image for a shift of -32.6,-16.2.
+<DATE><TIME>|<HOST>|I|testImageShift
+    Following should be an error...
+<DATE><TIME>|<HOST>|E|psLib.image.psImageShift
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|testImageShift
+    Following should be an error for invalid interpolation mode.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageShift
+    Specified interpolation mode, -1, is unsupported.
+
+---> TESTPOINT PASSED (psImage{psImageShift} | tst_psImageManip.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageManip.c                                         *
+*            TestPoint: psImage{psImageResample}                                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psLib.image.psImageResample
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageResample
+    Specified scale value, 0, must be a positive value.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageResample
+    Specified interpolation mode, 0, is unsupported.
+
+---> TESTPOINT PASSED (psImage{psImageResample} | tst_psImageManip.c)
+
Index: /branches/rel3/psLib/test/image/verified/tst_psImageStats00.stderr
===================================================================
--- /branches/rel3/psLib/test/image/verified/tst_psImageStats00.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/image/verified/tst_psImageStats00.stderr	(revision 2163)
@@ -0,0 +1,10 @@
+<DATE><TIME>|<HOST>|E|psImageHistogram
+    Unallowable operation: out is NULL.
+<DATE><TIME>|<HOST>|E|psImageHistogram
+    Unallowable operation: in is NULL.
+<DATE><TIME>|<HOST>|E|psImageHistogram
+    Unallowable operation: out is NULL.
+<DATE><TIME>|<HOST>|I|main
+    Following should be an error for invalid mask type.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageHistogram
+    Input psImage mask type, psS8, is not the supported mask datatype of psU8.
Index: /branches/rel3/psLib/test/image/verified/tst_psImageStats00.stdout
===================================================================
--- /branches/rel3/psLib/test/image/verified/tst_psImageStats00.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/image/verified/tst_psImageStats00.stdout	(revision 2163)
@@ -0,0 +1,429 @@
+*******************************
+* IMAGE SIZE is (1 by 1)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram, no mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.0 - 0.1) data (1)
+Bin number 1 bounds: (0.1 - 0.2) data (0)
+Bin number 2 bounds: (0.2 - 0.3) data (0)
+Bin number 3 bounds: (0.3 - 0.4) data (0)
+Bin number 4 bounds: (0.4 - 0.5) data (0)
+Bin number 5 bounds: (0.5 - 0.6) data (0)
+Bin number 6 bounds: (0.6 - 0.7) data (0)
+Bin number 7 bounds: (0.7 - 0.8) data (0)
+Bin number 8 bounds: (0.8 - 0.9) data (0)
+Bin number 9 bounds: (0.9 - 1.0) data (0)
+Bin number 10 bounds: (1.0 - 1.1) data (0)
+Bin number 11 bounds: (1.1 - 1.2) data (0)
+Bin number 12 bounds: (1.2 - 1.3) data (0)
+Bin number 13 bounds: (1.3 - 1.4) data (0)
+Bin number 14 bounds: (1.4 - 1.5) data (0)
+Bin number 15 bounds: (1.5 - 1.6) data (0)
+Bin number 16 bounds: (1.6 - 1.7) data (0)
+Bin number 17 bounds: (1.7 - 1.8) data (0)
+Bin number 18 bounds: (1.8 - 1.9) data (0)
+Bin number 19 bounds: (1.9 - 2.0) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram, no mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram with mask}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.00 - 0.10) data (1)
+Bin number 1 bounds: (0.10 - 0.20) data (0)
+Bin number 2 bounds: (0.20 - 0.30) data (0)
+Bin number 3 bounds: (0.30 - 0.40) data (0)
+Bin number 4 bounds: (0.40 - 0.50) data (0)
+Bin number 5 bounds: (0.50 - 0.60) data (0)
+Bin number 6 bounds: (0.60 - 0.70) data (0)
+Bin number 7 bounds: (0.70 - 0.80) data (0)
+Bin number 8 bounds: (0.80 - 0.90) data (0)
+Bin number 9 bounds: (0.90 - 1.00) data (0)
+Bin number 10 bounds: (1.00 - 1.10) data (0)
+Bin number 11 bounds: (1.10 - 1.20) data (0)
+Bin number 12 bounds: (1.20 - 1.30) data (0)
+Bin number 13 bounds: (1.30 - 1.40) data (0)
+Bin number 14 bounds: (1.40 - 1.50) data (0)
+Bin number 15 bounds: (1.50 - 1.60) data (0)
+Bin number 16 bounds: (1.60 - 1.70) data (0)
+Bin number 17 bounds: (1.70 - 1.80) data (0)
+Bin number 18 bounds: (1.80 - 1.90) data (0)
+Bin number 19 bounds: (1.90 - 2.00) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram with mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psHistogram/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psHistogram/psImage structure.} | tst_psImageStats00.c)
+
+*******************************
+* IMAGE SIZE is (1 by 32)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram, no mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.0 - 1.7) data (2)
+Bin number 1 bounds: (1.7 - 3.3) data (2)
+Bin number 2 bounds: (3.3 - 5.0) data (1)
+Bin number 3 bounds: (5.0 - 6.6) data (2)
+Bin number 4 bounds: (6.6 - 8.2) data (2)
+Bin number 5 bounds: (8.2 - 9.9) data (1)
+Bin number 6 bounds: (9.9 - 11.6) data (2)
+Bin number 7 bounds: (11.6 - 13.2) data (2)
+Bin number 8 bounds: (13.2 - 14.9) data (1)
+Bin number 9 bounds: (14.9 - 16.5) data (2)
+Bin number 10 bounds: (16.5 - 18.2) data (2)
+Bin number 11 bounds: (18.2 - 19.8) data (1)
+Bin number 12 bounds: (19.8 - 21.5) data (2)
+Bin number 13 bounds: (21.5 - 23.1) data (2)
+Bin number 14 bounds: (23.1 - 24.8) data (1)
+Bin number 15 bounds: (24.8 - 26.4) data (2)
+Bin number 16 bounds: (26.4 - 28.1) data (1)
+Bin number 17 bounds: (28.1 - 29.7) data (2)
+Bin number 18 bounds: (29.7 - 31.4) data (2)
+Bin number 19 bounds: (31.4 - 33.0) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram, no mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram with mask}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.00 - 1.65) data (2)
+Bin number 1 bounds: (1.65 - 3.30) data (2)
+Bin number 2 bounds: (3.30 - 4.95) data (1)
+Bin number 3 bounds: (4.95 - 6.60) data (2)
+Bin number 4 bounds: (6.60 - 8.25) data (2)
+Bin number 5 bounds: (8.25 - 9.90) data (1)
+Bin number 6 bounds: (9.90 - 11.55) data (2)
+Bin number 7 bounds: (11.55 - 13.20) data (2)
+Bin number 8 bounds: (13.20 - 14.85) data (1)
+Bin number 9 bounds: (14.85 - 16.50) data (2)
+Bin number 10 bounds: (16.50 - 18.15) data (2)
+Bin number 11 bounds: (18.15 - 19.80) data (1)
+Bin number 12 bounds: (19.80 - 21.45) data (2)
+Bin number 13 bounds: (21.45 - 23.10) data (2)
+Bin number 14 bounds: (23.10 - 24.75) data (1)
+Bin number 15 bounds: (24.75 - 26.40) data (2)
+Bin number 16 bounds: (26.40 - 28.05) data (1)
+Bin number 17 bounds: (28.05 - 29.70) data (2)
+Bin number 18 bounds: (29.70 - 31.35) data (2)
+Bin number 19 bounds: (31.35 - 33.00) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram with mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psHistogram/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psHistogram/psImage structure.} | tst_psImageStats00.c)
+
+*******************************
+* IMAGE SIZE is (32 by 1)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram, no mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.0 - 1.7) data (2)
+Bin number 1 bounds: (1.7 - 3.3) data (2)
+Bin number 2 bounds: (3.3 - 5.0) data (1)
+Bin number 3 bounds: (5.0 - 6.6) data (2)
+Bin number 4 bounds: (6.6 - 8.2) data (2)
+Bin number 5 bounds: (8.2 - 9.9) data (1)
+Bin number 6 bounds: (9.9 - 11.6) data (2)
+Bin number 7 bounds: (11.6 - 13.2) data (2)
+Bin number 8 bounds: (13.2 - 14.9) data (1)
+Bin number 9 bounds: (14.9 - 16.5) data (2)
+Bin number 10 bounds: (16.5 - 18.2) data (2)
+Bin number 11 bounds: (18.2 - 19.8) data (1)
+Bin number 12 bounds: (19.8 - 21.5) data (2)
+Bin number 13 bounds: (21.5 - 23.1) data (2)
+Bin number 14 bounds: (23.1 - 24.8) data (1)
+Bin number 15 bounds: (24.8 - 26.4) data (2)
+Bin number 16 bounds: (26.4 - 28.1) data (1)
+Bin number 17 bounds: (28.1 - 29.7) data (2)
+Bin number 18 bounds: (29.7 - 31.4) data (2)
+Bin number 19 bounds: (31.4 - 33.0) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram, no mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram with mask}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.00 - 1.65) data (2)
+Bin number 1 bounds: (1.65 - 3.30) data (2)
+Bin number 2 bounds: (3.30 - 4.95) data (1)
+Bin number 3 bounds: (4.95 - 6.60) data (2)
+Bin number 4 bounds: (6.60 - 8.25) data (2)
+Bin number 5 bounds: (8.25 - 9.90) data (1)
+Bin number 6 bounds: (9.90 - 11.55) data (2)
+Bin number 7 bounds: (11.55 - 13.20) data (2)
+Bin number 8 bounds: (13.20 - 14.85) data (1)
+Bin number 9 bounds: (14.85 - 16.50) data (2)
+Bin number 10 bounds: (16.50 - 18.15) data (2)
+Bin number 11 bounds: (18.15 - 19.80) data (1)
+Bin number 12 bounds: (19.80 - 21.45) data (2)
+Bin number 13 bounds: (21.45 - 23.10) data (2)
+Bin number 14 bounds: (23.10 - 24.75) data (1)
+Bin number 15 bounds: (24.75 - 26.40) data (2)
+Bin number 16 bounds: (26.40 - 28.05) data (1)
+Bin number 17 bounds: (28.05 - 29.70) data (2)
+Bin number 18 bounds: (29.70 - 31.35) data (2)
+Bin number 19 bounds: (31.35 - 33.00) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram with mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psHistogram/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psHistogram/psImage structure.} | tst_psImageStats00.c)
+
+*******************************
+* IMAGE SIZE is (32 by 32)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram, no mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.0 - 3.2) data (10)
+Bin number 1 bounds: (3.2 - 6.4) data (18)
+Bin number 2 bounds: (6.4 - 9.6) data (27)
+Bin number 3 bounds: (9.6 - 12.8) data (36)
+Bin number 4 bounds: (12.8 - 16.0) data (45)
+Bin number 5 bounds: (16.0 - 19.2) data (74)
+Bin number 6 bounds: (19.2 - 22.4) data (66)
+Bin number 7 bounds: (22.4 - 25.6) data (75)
+Bin number 8 bounds: (25.6 - 28.8) data (84)
+Bin number 9 bounds: (28.8 - 32.0) data (93)
+Bin number 10 bounds: (32.0 - 35.2) data (118)
+Bin number 11 bounds: (35.2 - 38.4) data (78)
+Bin number 12 bounds: (38.4 - 41.6) data (69)
+Bin number 13 bounds: (41.6 - 44.8) data (60)
+Bin number 14 bounds: (44.8 - 48.0) data (51)
+Bin number 15 bounds: (48.0 - 51.2) data (54)
+Bin number 16 bounds: (51.2 - 54.4) data (30)
+Bin number 17 bounds: (54.4 - 57.6) data (21)
+Bin number 18 bounds: (57.6 - 60.8) data (12)
+Bin number 19 bounds: (60.8 - 64.0) data (3)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram, no mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram with mask}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.00 - 3.20) data (10)
+Bin number 1 bounds: (3.20 - 6.40) data (18)
+Bin number 2 bounds: (6.40 - 9.60) data (27)
+Bin number 3 bounds: (9.60 - 12.80) data (36)
+Bin number 4 bounds: (12.80 - 16.00) data (45)
+Bin number 5 bounds: (16.00 - 19.20) data (74)
+Bin number 6 bounds: (19.20 - 22.40) data (66)
+Bin number 7 bounds: (22.40 - 25.60) data (75)
+Bin number 8 bounds: (25.60 - 28.80) data (84)
+Bin number 9 bounds: (28.80 - 32.00) data (93)
+Bin number 10 bounds: (32.00 - 35.20) data (115)
+Bin number 11 bounds: (35.20 - 38.40) data (66)
+Bin number 12 bounds: (38.40 - 41.60) data (48)
+Bin number 13 bounds: (41.60 - 44.80) data (30)
+Bin number 14 bounds: (44.80 - 48.00) data (12)
+Bin number 15 bounds: (48.00 - 51.20) data (0)
+Bin number 16 bounds: (51.20 - 54.40) data (0)
+Bin number 17 bounds: (54.40 - 57.60) data (0)
+Bin number 18 bounds: (57.60 - 60.80) data (0)
+Bin number 19 bounds: (60.80 - 64.00) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram with mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psHistogram/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psHistogram/psImage structure.} | tst_psImageStats00.c)
+
+*******************************
+* IMAGE SIZE is (32 by 64)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram, no mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.0 - 4.8) data (15)
+Bin number 1 bounds: (4.8 - 9.6) data (40)
+Bin number 2 bounds: (9.6 - 14.4) data (65)
+Bin number 3 bounds: (14.4 - 19.2) data (90)
+Bin number 4 bounds: (19.2 - 24.0) data (90)
+Bin number 5 bounds: (24.0 - 28.8) data (135)
+Bin number 6 bounds: (28.8 - 33.6) data (157)
+Bin number 7 bounds: (33.6 - 38.4) data (160)
+Bin number 8 bounds: (38.4 - 43.2) data (160)
+Bin number 9 bounds: (43.2 - 48.0) data (128)
+Bin number 10 bounds: (48.0 - 52.8) data (160)
+Bin number 11 bounds: (52.8 - 57.6) data (160)
+Bin number 12 bounds: (57.6 - 62.4) data (160)
+Bin number 13 bounds: (62.4 - 67.2) data (150)
+Bin number 14 bounds: (67.2 - 72.0) data (102)
+Bin number 15 bounds: (72.0 - 76.8) data (105)
+Bin number 16 bounds: (76.8 - 81.6) data (80)
+Bin number 17 bounds: (81.6 - 86.4) data (55)
+Bin number 18 bounds: (86.4 - 91.2) data (30)
+Bin number 19 bounds: (91.2 - 96.0) data (6)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram, no mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram with mask}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.00 - 4.80) data (15)
+Bin number 1 bounds: (4.80 - 9.60) data (40)
+Bin number 2 bounds: (9.60 - 14.40) data (65)
+Bin number 3 bounds: (14.40 - 19.20) data (90)
+Bin number 4 bounds: (19.20 - 24.00) data (90)
+Bin number 5 bounds: (24.00 - 28.80) data (135)
+Bin number 6 bounds: (28.80 - 33.60) data (157)
+Bin number 7 bounds: (33.60 - 38.40) data (160)
+Bin number 8 bounds: (38.40 - 43.20) data (160)
+Bin number 9 bounds: (43.20 - 48.00) data (128)
+Bin number 10 bounds: (48.00 - 52.80) data (154)
+Bin number 11 bounds: (52.80 - 57.60) data (130)
+Bin number 12 bounds: (57.60 - 62.40) data (105)
+Bin number 13 bounds: (62.40 - 67.20) data (76)
+Bin number 14 bounds: (67.20 - 72.00) data (42)
+Bin number 15 bounds: (72.00 - 76.80) data (30)
+Bin number 16 bounds: (76.80 - 81.60) data (6)
+Bin number 17 bounds: (81.60 - 86.40) data (0)
+Bin number 18 bounds: (86.40 - 91.20) data (0)
+Bin number 19 bounds: (91.20 - 96.00) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram with mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psHistogram/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psHistogram/psImage structure.} | tst_psImageStats00.c)
+
+*******************************
+* IMAGE SIZE is (64 by 32)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram, no mask}       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.0 - 4.8) data (15)
+Bin number 1 bounds: (4.8 - 9.6) data (40)
+Bin number 2 bounds: (9.6 - 14.4) data (65)
+Bin number 3 bounds: (14.4 - 19.2) data (90)
+Bin number 4 bounds: (19.2 - 24.0) data (90)
+Bin number 5 bounds: (24.0 - 28.8) data (135)
+Bin number 6 bounds: (28.8 - 33.6) data (157)
+Bin number 7 bounds: (33.6 - 38.4) data (160)
+Bin number 8 bounds: (38.4 - 43.2) data (160)
+Bin number 9 bounds: (43.2 - 48.0) data (128)
+Bin number 10 bounds: (48.0 - 52.8) data (160)
+Bin number 11 bounds: (52.8 - 57.6) data (160)
+Bin number 12 bounds: (57.6 - 62.4) data (160)
+Bin number 13 bounds: (62.4 - 67.2) data (150)
+Bin number 14 bounds: (67.2 - 72.0) data (102)
+Bin number 15 bounds: (72.0 - 76.8) data (105)
+Bin number 16 bounds: (76.8 - 81.6) data (80)
+Bin number 17 bounds: (81.6 - 86.4) data (55)
+Bin number 18 bounds: (86.4 - 91.2) data (30)
+Bin number 19 bounds: (91.2 - 96.0) data (6)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram, no mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calculate Histogram with mask}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Bin number 0 bounds: (0.00 - 4.80) data (15)
+Bin number 1 bounds: (4.80 - 9.60) data (40)
+Bin number 2 bounds: (9.60 - 14.40) data (65)
+Bin number 3 bounds: (14.40 - 19.20) data (90)
+Bin number 4 bounds: (19.20 - 24.00) data (90)
+Bin number 5 bounds: (24.00 - 28.80) data (135)
+Bin number 6 bounds: (28.80 - 33.60) data (157)
+Bin number 7 bounds: (33.60 - 38.40) data (160)
+Bin number 8 bounds: (38.40 - 43.20) data (160)
+Bin number 9 bounds: (43.20 - 48.00) data (128)
+Bin number 10 bounds: (48.00 - 52.80) data (154)
+Bin number 11 bounds: (52.80 - 57.60) data (130)
+Bin number 12 bounds: (57.60 - 62.40) data (105)
+Bin number 13 bounds: (62.40 - 67.20) data (76)
+Bin number 14 bounds: (67.20 - 72.00) data (42)
+Bin number 15 bounds: (72.00 - 76.80) data (30)
+Bin number 16 bounds: (76.80 - 81.60) data (6)
+Bin number 17 bounds: (81.60 - 86.40) data (0)
+Bin number 18 bounds: (86.40 - 91.20) data (0)
+Bin number 19 bounds: (91.20 - 96.00) data (0)
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Histogram with mask} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psHistogram/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psHistogram/psImage structure.} | tst_psImageStats00.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats00.c                                       *
+*            TestPoint: psImageStats functions{Calling psImageHistogram() with NULL parameters} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Calling psImageHistogram() with NULL parameters} | tst_psImageStats00.c)
+
Index: /branches/rel3/psLib/test/image/verified/tst_psImageStats01.stderr
===================================================================
--- /branches/rel3/psLib/test/image/verified/tst_psImageStats01.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/image/verified/tst_psImageStats01.stderr	(revision 2163)
@@ -0,0 +1,8 @@
+<DATE><TIME>|<HOST>|E|psLib.image.psImageStats
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageStats
+    Specified statistic can not be NULL.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageStats
+    Specified statistic option did not indicate any operation to perform.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageStats
+    Input psImage mask type, psU32, is not the supported mask datatype of psU8.
Index: /branches/rel3/psLib/test/image/verified/tst_psImageStats01.stdout
===================================================================
--- /branches/rel3/psLib/test/image/verified/tst_psImageStats01.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/image/verified/tst_psImageStats01.stdout	(revision 2163)
@@ -0,0 +1,201 @@
+*******************************
+* IMAGE SIZE is (1 by 1)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean, no mask %d}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 0.00
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean, no mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean with mask}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 0.00
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean with mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psStats/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psStats/psImage structure.} | tst_psImageStats01.c)
+
+*******************************
+* IMAGE SIZE is (1 by 32)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean, no mask %d}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 15.50
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean, no mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean with mask}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 15.50
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean with mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psStats/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psStats/psImage structure.} | tst_psImageStats01.c)
+
+*******************************
+* IMAGE SIZE is (32 by 1)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean, no mask %d}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 15.50
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean, no mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean with mask}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 15.50
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean with mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psStats/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psStats/psImage structure.} | tst_psImageStats01.c)
+
+*******************************
+* IMAGE SIZE is (32 by 32)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean, no mask %d}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 31.00
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean, no mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean with mask}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 26.21
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean with mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psStats/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psStats/psImage structure.} | tst_psImageStats01.c)
+
+*******************************
+* IMAGE SIZE is (32 by 64)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean, no mask %d}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 47.00
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean, no mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean with mask}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 39.66
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean with mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psStats/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psStats/psImage structure.} | tst_psImageStats01.c)
+
+*******************************
+* IMAGE SIZE is (64 by 32)
+*******************************
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean, no mask %d}  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 47.00
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean, no mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Calculate Sample Mean with mask}    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+The sample mean was 39.66
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Sample Mean with mask} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psStats/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psStats/psImage structure.} | tst_psImageStats01.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats01.c                                       *
+*            TestPoint: psImageStats functions{Test With Various Null Inputs}      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Test With Various Null Inputs} | tst_psImageStats01.c)
+
Index: /branches/rel3/psLib/test/image/verified/tst_psImageStats02.stderr
===================================================================
--- /branches/rel3/psLib/test/image/verified/tst_psImageStats02.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/image/verified/tst_psImageStats02.stderr	(revision 2163)
@@ -0,0 +1,16 @@
+<DATE><TIME>|<HOST>|I|main
+    Following should be an error message for NULL coeffs argument.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageFitPolynomial
+    Polynomial coefficients cannot be NULL. 
+<DATE><TIME>|<HOST>|I|main
+    Following should be a error message for NULL input argument.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageFitPolynomial
+    Can not operate on a NULL psImage.
+<DATE><TIME>|<HOST>|I|main
+    Following should be an error message for NULL coeffs argument.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageEvalPolynomial
+    Polynomial coefficients cannot be NULL. 
+<DATE><TIME>|<HOST>|I|main
+    Following should be a error message for NULL input argument.
+<DATE><TIME>|<HOST>|E|psLib.image.psImageEvalPolynomial
+    Can not operate on a NULL psImage.
Index: /branches/rel3/psLib/test/image/verified/tst_psImageStats02.stdout
===================================================================
--- /branches/rel3/psLib/test/image/verified/tst_psImageStats02.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/image/verified/tst_psImageStats02.stdout	(revision 2163)
@@ -0,0 +1,91 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats02.c                                       *
+*            TestPoint: psImageStats functions{Calculate Chebyshev Polynomials, no mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Cheby Polynomial (0, 0) coefficient is 189.00
+Cheby Polynomial (0, 1) coefficient is 25.94
+Cheby Polynomial (0, 2) coefficient is 0.00
+Cheby Polynomial (0, 3) coefficient is 2.88
+Cheby Polynomial (0, 4) coefficient is 0.00
+Cheby Polynomial (0, 5) coefficient is 1.04
+Cheby Polynomial (0, 6) coefficient is 0.00
+Cheby Polynomial (0, 7) coefficient is 0.53
+Cheby Polynomial (1, 0) coefficient is 129.68
+Cheby Polynomial (1, 1) coefficient is 0.00
+Cheby Polynomial (1, 2) coefficient is 0.00
+Cheby Polynomial (1, 3) coefficient is 0.00
+Cheby Polynomial (1, 4) coefficient is 0.00
+Cheby Polynomial (1, 5) coefficient is 0.00
+Cheby Polynomial (1, 6) coefficient is 0.00
+Cheby Polynomial (1, 7) coefficient is 0.00
+Cheby Polynomial (2, 0) coefficient is 0.00
+Cheby Polynomial (2, 1) coefficient is 0.00
+Cheby Polynomial (2, 2) coefficient is 0.00
+Cheby Polynomial (2, 3) coefficient is 0.00
+Cheby Polynomial (2, 4) coefficient is 0.00
+Cheby Polynomial (2, 5) coefficient is 0.00
+Cheby Polynomial (2, 6) coefficient is 0.00
+Cheby Polynomial (2, 7) coefficient is 0.00
+Cheby Polynomial (3, 0) coefficient is 14.40
+Cheby Polynomial (3, 1) coefficient is 0.00
+Cheby Polynomial (3, 2) coefficient is 0.00
+Cheby Polynomial (3, 3) coefficient is 0.00
+Cheby Polynomial (3, 4) coefficient is 0.00
+Cheby Polynomial (3, 5) coefficient is 0.00
+Cheby Polynomial (3, 6) coefficient is 0.00
+Cheby Polynomial (3, 7) coefficient is 0.00
+Cheby Polynomial (4, 0) coefficient is 0.00
+Cheby Polynomial (4, 1) coefficient is 0.00
+Cheby Polynomial (4, 2) coefficient is 0.00
+Cheby Polynomial (4, 3) coefficient is 0.00
+Cheby Polynomial (4, 4) coefficient is 0.00
+Cheby Polynomial (4, 5) coefficient is 0.00
+Cheby Polynomial (4, 6) coefficient is 0.00
+Cheby Polynomial (4, 7) coefficient is 0.00
+Cheby Polynomial (5, 0) coefficient is 5.17
+Cheby Polynomial (5, 1) coefficient is 0.00
+Cheby Polynomial (5, 2) coefficient is 0.00
+Cheby Polynomial (5, 3) coefficient is 0.00
+Cheby Polynomial (5, 4) coefficient is 0.00
+Cheby Polynomial (5, 5) coefficient is 0.00
+Cheby Polynomial (5, 6) coefficient is 0.00
+Cheby Polynomial (5, 7) coefficient is 0.00
+Cheby Polynomial (6, 0) coefficient is 0.00
+Cheby Polynomial (6, 1) coefficient is 0.00
+Cheby Polynomial (6, 2) coefficient is 0.00
+Cheby Polynomial (6, 3) coefficient is 0.00
+Cheby Polynomial (6, 4) coefficient is 0.00
+Cheby Polynomial (6, 5) coefficient is 0.00
+Cheby Polynomial (6, 6) coefficient is 0.00
+Cheby Polynomial (6, 7) coefficient is 0.00
+Cheby Polynomial (7, 0) coefficient is 2.63
+Cheby Polynomial (7, 1) coefficient is 0.00
+Cheby Polynomial (7, 2) coefficient is 0.00
+Cheby Polynomial (7, 3) coefficient is 0.00
+Cheby Polynomial (7, 4) coefficient is 0.00
+Cheby Polynomial (7, 5) coefficient is 0.00
+Cheby Polynomial (7, 6) coefficient is 0.00
+Cheby Polynomial (7, 7) coefficient is 0.00
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Chebyshev Polynomials, no mask} | tst_psImageStats02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats02.c                                       *
+*            TestPoint: psImageStats functions{Calculate Chebyshev Polynomials, no mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Calculate Chebyshev Polynomials, no mask} | tst_psImageStats02.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psImageStats02.c                                       *
+*            TestPoint: psImageStats functions{Deallocate the psStats/psImage structure.} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psImageStats functions{Deallocate the psStats/psImage structure.} | tst_psImageStats02.c)
+
Index: /branches/rel3/psLib/test/psTest.c
===================================================================
--- /branches/rel3/psLib/test/psTest.c	(revision 2163)
+++ /branches/rel3/psLib/test/psTest.c	(revision 2163)
@@ -0,0 +1,244 @@
+//
+// C Implementation: psTest
+//
+// Description:
+//
+//
+// Author: Robert DeSonia <robert.desonia@mhpcc.hpc.mil>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "psTest.h"
+#include "psMemory.h"
+#include "psError.h"
+#include "psTrace.h"
+
+#define HEADER_TOP    "/***************************** TESTPOINT ******************************************\\\n"
+#define HEADER_LINE_STRING   "* %20s: %-58s *\n"
+#define HEADER_LINE_INT      "* %20s: %-58d *\n"
+#define HEADER_BOTTOM "\\**********************************************************************************/\n\n"
+
+bool p_runTestSuite( FILE *fp, const char* testPointFile, const char* packageName,
+                     testDescription tests[], int argc, char * const argv[] )
+{
+    bool success = true;
+    bool runAll = true;
+    bool useFork = true;
+    bool found;
+    int c;
+    int n;
+    extern char *optarg;
+
+    if ( argc > 0 ) {
+        while ( ( c = getopt( argc, argv, "lhn:dt:" ) ) != -1 ) {
+            switch ( c ) {
+            case 'h':
+                printf( "Usage: %s [-l] [-d] [-h] [-n=Testpoint#] [-t=TestpointName]\n"
+                        "    where:\n"
+                        "           -l  : lists the testpoints contained in this test driver executable\n"
+                        "           -d  : turns on debugger-friendly mode (no forking, aborts/signals are not handled)\n"
+                        "           -h  : prints this help\n"
+                        "           -n  : specifies a particular testpoint by number to run\n"
+                        "           -t  : specifies a particular testpoint by name to run\n"
+                        "    (if no -l, -n or -t options are given, all testpoints are run)\n",
+                        argv[ 0 ] );
+                runAll = false;
+                break;
+            case 'd':
+                useFork = false;
+                break;
+            case 'l':
+                printf( "Test Driver:  %s\n", testPointFile );
+                printf( "Package Name: %s\n", packageName );
+                printf( "Testpoints:\n" );
+                runAll = false;
+                for ( int index = 0; tests[ index ].fcn != NULL; index++ ) {
+                    printf( "    %6d - %s \n", tests[ index ].testPointNumber,
+                            tests[ index ].testPointName );
+                }
+                printf( "\n" );
+                break;
+            case 't':
+                runAll = false;
+                for ( int index = 0; tests[ index ].fcn != NULL; index++ ) {
+                    if ( strcmp( optarg, tests[ index ].testPointName ) == 0 ) {
+                        success = p_runTest( fp,
+                                             testPointFile,
+                                             packageName,
+                                             tests[ index ].testPointName,
+                                             tests[ index ].fcn,
+                                             tests[ index ].expectedReturn,
+                                             useFork ) && success;
+                    }
+                }
+                break;
+            case 'n':
+                runAll = false;
+                if ( sscanf( optarg, "%i", &n ) != 1 ) {
+                    psError( __func__, "Failed to parse the testpoint number (%s).",
+                             optarg );
+                    break;
+                }
+                found = false;
+                for ( int index = 0; tests[ index ].fcn != NULL; index++ ) {
+                    if ( n == tests[ index ].testPointNumber ) {
+                        found = true;
+                        success = p_runTest( fp,
+                                             testPointFile,
+                                             packageName,
+                                             tests[ index ].testPointName,
+                                             tests[ index ].fcn,
+                                             tests[ index ].expectedReturn,
+                                             useFork ) && success;
+                    }
+                }
+                if ( ! found ) {
+                    psError( __func__, "The specified testpoint number (%d) doesn't exist in this test driver.",
+                             n );
+                    break;
+                }
+                break;
+            case '?':
+                psError( __func__, "Option %s is not recognized and is ignored.", optarg );
+                break;
+            }
+        }
+    }
+
+    if ( runAll ) {
+        for ( int index = 0; tests[ index ].fcn != NULL; index++ ) {
+            if ( ! tests[ index ].isDuplicateEntry ) {
+                success = p_runTest( fp,
+                                     testPointFile,
+                                     packageName,
+                                     tests[ index ].testPointName,
+                                     tests[ index ].fcn,
+                                     tests[ index ].expectedReturn,
+                                     useFork ) && success;
+            }
+        }
+    }
+
+    if ( ! success ) {
+        psError( testPointFile, "One or more tests failed" );
+    }
+
+    return success;
+}
+
+bool p_runTest( FILE *fp, const char* testPointFile, const char* packageName, const char* testPointName,
+                testFcn fcn, int expectedReturn, bool useFork )
+{
+    int childReturn = 0;
+    pid_t child;
+
+    p_printPositiveTestHeader( fp, testPointFile, packageName, testPointName );
+
+    if ( useFork ) {
+        child = fork();
+        if ( child == 0 ) {                   // I am the child process, run the test
+            int currentId = psMemGetId();
+            int retVal = fcn();
+            if ( retVal == 0 ) { // only bother checking memory if test executed to end.
+                if ( psMemCheckLeaks( currentId, NULL, stderr ) != 0 ) {
+                    psError( __func__, "Memory Leaks Detected" );
+                    retVal = 64;
+                }
+                psMemCheckCorruption( 1 );
+            }
+            exit( retVal );
+        } else
+            if ( child < 0 ) {
+                fprintf( fp, "Couldn't fork a process to run a negative test (%s|%s)",
+                         packageName, testPointName );
+                abort();
+            }
+
+        waitpid( child, &childReturn, 0 );
+        if ( WIFSIGNALED( childReturn ) ) {
+            childReturn = -WTERMSIG( childReturn );
+        } else {
+            childReturn = WEXITSTATUS( childReturn );
+        }
+    } else {
+        int currentId = psMemGetId();
+        childReturn = fcn();
+        if ( childReturn == 0 ) { // only bother checking memory if test executed to end.
+            if ( psMemCheckLeaks( currentId, NULL, stderr ) != 0 ) {
+                psError( __func__, "Memory Leaks Detected" );
+                childReturn = 64;
+            }
+            psMemCheckCorruption( 1 );
+        }
+    }
+
+
+    if ( childReturn != expectedReturn ) {
+        fprintf( fp, "Return value mismatch: expected %d, got %d",
+                 expectedReturn, childReturn );
+    }
+
+    p_printFooter( fp, testPointFile, packageName, testPointName,
+                   ( childReturn == expectedReturn ) );
+
+    return ( childReturn == expectedReturn );
+}
+
+void p_printPositiveTestHeader( FILE *fp,
+                                const char* testPointFile,
+                                const char* packageName,
+                                const char* testPointName )
+{
+    char TP[ 80 ];
+
+    snprintf( TP, 80, "%s{%s}", packageName, testPointName );
+
+    fprintf( fp, HEADER_TOP );
+    fprintf( fp, HEADER_LINE_STRING, "TestFile", testPointFile );
+    fprintf( fp, HEADER_LINE_STRING, "TestPoint", TP );
+    fprintf( fp, HEADER_LINE_STRING, "TestType", "Positive" );
+    fprintf( fp, HEADER_BOTTOM );
+}
+
+void p_printNegativeTestHeader( FILE *fp,
+                                const char* testPointFile,
+                                const char* packageName,
+                                const char* testPointName,
+                                const char* expectedError,
+                                int exitValue )
+{
+    char TP[ 80 ];
+
+    snprintf( TP, 80, "%s{%s}", packageName, testPointName );
+
+    fprintf( fp, HEADER_TOP );
+    fprintf( fp, HEADER_LINE_STRING, "TestFile", testPointFile );
+    fprintf( fp, HEADER_LINE_STRING, "TestPoint", TP );
+    fprintf( fp, HEADER_LINE_STRING, "TestType", "Negative" );
+    fprintf( fp, HEADER_LINE_STRING, "ExpectedErrorText", expectedError );
+    fprintf( fp, HEADER_LINE_INT, "ExpectedStatusValue", exitValue );
+    fprintf( fp, HEADER_BOTTOM );
+}
+
+
+void p_printFooter( FILE *fp,
+                    const char* testPointFile,
+                    const char* packageName,
+                    const char* testPointName,
+                    bool success )
+{
+    if ( success ) {
+        fprintf( fp, "\n---> TESTPOINT PASSED (%s{%s} | %s)\n\n", packageName, testPointName, testPointFile );
+    } else {
+        fprintf( fp, "\n---> TESTPOINT FAILED (%s{%s} | %s)\n\n", packageName, testPointName, testPointFile );
+    }
+}
Index: /branches/rel3/psLib/test/psTest.h
===================================================================
--- /branches/rel3/psLib/test/psTest.h	(revision 2163)
+++ /branches/rel3/psLib/test/psTest.h	(revision 2163)
@@ -0,0 +1,81 @@
+
+#ifndef PSTEST_H
+#define PSTEST_H
+
+#include <stdio.h>
+#include <stdbool.h>
+
+#define printPositiveTestHeader(filePtr, packageName, testPointName) \
+p_printPositiveTestHeader(filePtr, __FILE__, packageName, testPointName)
+
+#define printNegativeTestHeader(filePtr, packageName, testPointName, expectedError, exitValue) \
+p_printNegativeTestHeader(filePtr, __FILE__, packageName, testPointName, expectedError, exitValue)
+
+#define printFooter(filePtr, packageName, testPointName, success) \
+p_printFooter(filePtr, __FILE__, packageName, testPointName, success)
+
+typedef int (*testFcn)(void);
+
+typedef struct
+{
+    testFcn     fcn;
+    int         testPointNumber;
+    const char* testPointName;
+    int         expectedReturn;
+    bool        isDuplicateEntry;
+}
+testDescription;
+
+#define runTest(filePtr, packageName, testPointName, fcn, expectedReturn, useFork) \
+p_runTest(filePtr, __FILE__, packageName, testPointName, fcn, expectedReturn, useFork)
+
+#define runTestSuite(filePtr, packageName, tests, argc, argv) \
+p_runTestSuite(filePtr, __FILE__, packageName, tests, argc, argv)
+
+
+/////////////////////////// PRIVATE FUNCTIONS //////////////////////////////
+
+bool p_runTest(
+    FILE *fp,
+    const char* testPointFile,
+    const char* packageName,
+    const char* testPointName,
+    testFcn fcn,
+    int expectedReturn,
+    bool useFork
+);
+
+bool p_runTestSuite(
+    FILE *fp,
+    const char* testPointFile,
+    const char* packageName,
+    testDescription tests[],
+    int argc,
+    char * const argv[]
+);
+
+void p_printPositiveTestHeader(
+    FILE *fp,
+    const char* testPointFile,
+    const char* packageName,
+    const char* testPointName
+);
+
+void p_printNegativeTestHeader(
+    FILE *fp,
+    const char* testPointFile,
+    const char* packageName,
+    const char* testPointName,
+    const char* expectedError,
+    int exitValue
+);
+
+void p_printFooter(
+    FILE *fp,
+    const char* testPointFile,
+    const char* packageName,
+    const char* testPointName,
+    bool success
+);
+
+#endif
Index: /branches/rel3/psLib/test/runTest
===================================================================
--- /branches/rel3/psLib/test/runTest	(revision 2163)
+++ /branches/rel3/psLib/test/runTest	(revision 2163)
@@ -0,0 +1,388 @@
+#!/usr/bin/perl
+#
+#  This is a perl script to execute a single test driver program.  The script
+#  will examine the return value of the test driver and capture STDOUT, STDERR
+#  to files.  If the return value of the test driver is not zero, the test is
+#  deemed a failure.  STDOUT and STDERR files will be place in a subdirectory
+#  named temp and the files will be compared with verified STDOUT, STDERR files
+#  in a subdirectory named verified.  If there are no STDOUT, STDERR files in
+#  the verified directory, the captured STDOUT, STDERR files will be scanned
+#  for words which indicate a failure.
+#
+#  Assumptions:  A verified subdirectory with STDOUT, STDERR files exists for
+#                the test driver specified in the arguements if an exact
+#                match of the streams STDOUT, STDERR is necessary.
+#
+#  Return values:
+#                 Bit mapped values
+#                 0    Test run successfull and all tests passed
+#                 1    Verified directory did not exist
+#                 2    Verified STDOUT file did not exist
+#                 4    Verified STDERR file did not exist
+#                 8    STDOUT files did not compare
+#                16    STDERR files did not compare
+#                32    Test driver doesn't exist or is not executable
+#                64    STDOUT captured contains error strings
+#               128    STDERR captured contains error strings
+#               256    Test driver did not return zero
+#
+#  SYNOSIS:  runTest testDriverName
+#
+#  $Revison:  $  $Name: not supported by cvs2svn $
+#  $Date: 2004-08-20 00:51:22 $
+#
+#  Copyright 2004 Maui High Performance Computering Center, University of Hawaii
+#
+################################################################################
+
+# Provides functions for handling long command line options
+use Getopt::Long;
+
+# Assign variables based on the presence of command line options to the script
+GetOptions(
+    "reset!"       => \$reset,
+    "resetStderr!" => \$resetStderr,
+    "resetStdout!" => \$resetStdout,
+    "help!"        => \$help
+);
+
+if ($help) {
+    print
+"Usage: runTest [--reset] [--resetStderr] [--resetStdout] testfile(s)\n\n";
+    exit(0);
+}
+
+if ($reset) {
+    $resetStderr = 1;
+    $resetStdout = 1;
+}
+
+# Initialize exit value
+$exitValue = 0;
+
+# Set up the PSLIB_ROOT environment variable if the user doesn't have it set
+if ( !$ENV{'PSLIB_ROOT'} ) {
+
+    # Use the directory directly above test
+    $PSLIB_ROOT = `cd ..;pwd`;
+
+    # Remove newline for the end of path returned
+    chomp($PSLIB_ROOT);
+
+    # Set the environment variable
+    $ENV{'PSLIB_ROOT'} = $PSLIB_ROOT;
+
+    # Display message that PSLIB_ROOT not found and set to
+    print("PSLIB_ROOT not found: set to $PSLIB_ROOT\n");
+}
+
+# Add PSLIB_ROOT/lib to LD_LIBRARY_PATH and DYLD_LIBRARY_PATH environment vars
+$ENV{'LD_LIBRARY_PATH'}   = "$ENV{'PSLIB_ROOT'}/lib:$ENV{'LD_LIBRARY_PATH'}";
+$ENV{'DYLD_LIBRARY_PATH'} = "$ENV{'PSLIB_ROOT'}/lib:$ENV{'DYLD_LIBRARY_PATH'}";
+
+# Loop through the arguements passed to the script
+foreach (@ARGV) {
+    chomp;
+    $testFile = $_;
+
+    # Check if a temp directory already exists in the current work directory
+    if ( !( -e "temp" ) ) {
+
+        # Create temp directory to store STDOUT, STDERR files during test run
+        `mkdir temp`;
+
+        # Display message of new directory created
+        print("Creating temp directory\n");
+    }
+
+    # Check if a verified directory exists in the current work directory
+    if ( !( -e "verified" ) ) {
+
+        # Display message that verified subdirectory doesn't exist
+        print("        Verified directory doesn't exist.\n");
+
+        # Exit script since the test cannot be run with verified files
+        $exitValue = 1;
+    }
+
+    # Check if the test driver file exists and is executable
+    if ( ( -e $testFile ) && ( -x $testFile ) ) {
+
+        # Display message the test driver is being executed
+        print("--- Executing test driver: $testFile\n");
+
+        # Invoke the test driver
+        system("./$testFile 1> temp/$testFile.stdout 2> temp/$testFile.stderr");
+
+        # Check the return value of the test driver.  A value other than 0
+        # indicates failure of the test driver unless the test driver is name
+        # with a leading 'a' which indicates the test driver is expecting an
+        # abort condition to terminate the driver.
+        if (   ( $? != 0 && ( $testFile !~ /^A/i ) )
+            || ( $? == 0 && ( $testFile =~ /^A/i ) ) )
+        {
+
+            # Display failure message with return value to user
+            if ( $? != 0 && ( $testFile !~ /^A/i ) ) {
+                print(
+"        Failed - Test Driver expected 0 return value (Return value $?)\n"
+                );
+            }
+            elsif ( $? == 0 && ( $testFile =~ /^A/i ) ) {
+                print(
+"        Failed - Test Driver expected abort (Return value $?)\n"
+                );
+            }
+            $exitValue |= 256;
+        }
+        else {
+
+            # Test driver succeeded.
+
+            # Create filtered version of stdout and stderr
+
+            # Open the STDOUT file for reading
+            open( OUTFILE, "< temp/$testFile.stdout" );
+
+            # Open mod file to place filtered STDOUT
+            open( MODFILE,  "> temp/$testFile.stdout.mod" );
+            open( MODFILE2, "> verified/$testFile.stdout" ) if $resetStdout;
+
+           # Replace the variable date, time and host information with constants
+            $hostname = `hostname`;
+            chop $hostname;
+            while (<OUTFILE>) {
+                s/\s+\d+:\d+:\d+\w/<TIME>/g;
+                s/\d+:\d+:\d+/<DATE>/g;
+                s/$hostname\s*/<HOST>/g;
+                s/: Line \d+/: Line <LINENO>/g;
+                s/\:\d+/\:<LINENO>/g;
+                s/allocate \d+ bytes at/allocate <N> bytes at/g;
+
+              # Filter lines with malloc.  This is an artifact of memory testing
+              # with the Mac testbed
+                if ( !m/\*\*\*\smalloc/ ) {
+                    print MODFILE ($_);
+                    print MODFILE2 ($_) if $resetStdout;
+                }
+            }
+
+            # Close mod file
+            close(MODFILE);
+            close(MODFILE2) if $resetStdout;
+
+            # Close STDERR file
+            close(OUTFILE);
+
+            # Open the STDERR file for reading
+            open( OUTFILE, "< temp/$testFile.stderr" );
+
+            # Open mod file to place filtered STDERR
+            open( MODFILE,  "> temp/$testFile.stderr.mod" );
+            open( MODFILE2, "> verified/$testFile.stderr" ) if $resetStderr;
+
+           # Replace the variable date, time and host information with constants
+            while (<OUTFILE>) {
+                s/\s+\d+:\d+:\d+\w/<TIME>/g;
+                s/\d+:\d+:\d+/<DATE>/g;
+                s/$hostname\s*/<HOST>/g;
+                s/: Line \d+/: Line <LINENO>/g;
+                s/\:\d+/\:<LINENO>/g;
+                s/allocate \d+ bytes at/allocate <N> bytes at/g;
+
+              # Filter lines with malloc.  This is an artifact of memory testing
+              # with the Mac testbed
+                if ( !m/\*\*\*\smalloc/ ) {
+                    print MODFILE ($_);
+                    print MODFILE2 ($_) if $resetStderr;
+                }
+            }
+
+            # Close mod file
+            close(MODFILE);
+            close(MODFILE2) if $resetStderr;
+
+            # Close STDERR file
+            close(OUTFILE);
+
+            # Compare STDOUT capture with verified file
+            $exitValue |= &compareStream("verified/$testFile.stdout");
+
+            # Check exit value to determine if verified file doesn't exist
+            if ( $exitValue & 2 ) {
+
+                # STDOUT verified doesn't exist.  Search STDOUT capture
+                # for strings indicating error or failure
+                $exitValue |= &errorStrSearch("$testFile.stdout");
+            }
+
+            # Compare STDERR capture with verified file
+            $exitValue |= &compareStream("verified/$testFile.stderr");
+
+            # Check exit value to determine if verified file doesn't exist
+            if ( $exitValue & 4 ) {
+
+                # STDERR verified doesn't exist.  Search STDERR capture
+                # for strings indicating error or failure
+                $exitValue |= &errorStrSearch("$testFile.stderr");
+            }
+        }
+    }
+    else {
+
+        # Since test driver doesn't exist or is not executable then display
+        # message to user.
+        print(
+"        Need to specify an executable test file within directory.\n"
+        );
+
+        # Exit value set to indicate test driver doesn't exist or not executable
+        $exitValue |= 32;
+    }
+}
+
+# Exit for the script with exit value
+# Ignore the first three bit flags in exitValue since there are not indicators
+# of a failed test
+if ( ( $exitValue >> 3 ) != 0 ) {
+    print("Test failed - return status = $exitValue\n\n");
+}
+else {
+    print("Test successful\n\n");
+}
+exit($exitValue);
+
+################################################################################
+#
+#  SUBROUTINE: errorStrSearch
+#
+#      Description:  This subroutine will search the file specified in its
+#                    parameter for error strings and if they do exists
+#                    the appropriate value will be returned.
+#
+#      Parameter(s): fileName - input file to search for strings
+#
+#      Return:   0  -  No error strings found
+#               64  -  Error strings found in STDOUT
+#              128  -  Error strings found in STDERR
+#
+###############################################################################
+
+sub errorStrSearch {
+    local ($fileName)  = @_;
+    local ($returnVal) = 0;
+
+    # Open the captured file
+    open( CAPT_FILE, "<temp/$fileName" );
+
+    # Scan through all the lines of the file searching for error strings
+    while (<CAPT_FILE>) {
+        if (   m/FAIL/i
+            || m/FAULT/i
+            || m/ERROR/i
+            || m/Not Found/i
+            || m/SIGNAL/i
+            || m/NO SUCH FILE/i
+            || m/\|E\|/i
+            || m/\|A\|/i )
+        {
+            if ( $fileName =~ m/out/ ) {
+                print(
+                    "        Failed - File $fileName contains error strings.\n"
+                );
+                $returnVal = 64;
+            }
+            elsif ( $fileName =~ m/err/ ) {
+                print(
+                    "        Failed - File $fileName contains error strings.\n"
+                );
+                $returnVal = 128;
+            }
+            last;
+        }
+    }
+
+    # Close the capture file
+    close(CAPT_FILE);
+
+    # Return the return value
+    return ($returnVal);
+}
+
+################################################################################
+#
+#  SUBROUTINE: compareStream
+#
+#      Description:  This subroutine will compare the captured stream file with
+#                    a file in the verified directory if one exists.
+#
+#      Parameter(s): streamFile - input file to compare
+#
+#      Return:   0  -  Compare successful
+#                2  -  STDOUT verified file doesn't exist
+#                4  -  STDERR verified file doesn't exist
+#                8  -  STDOUT verified file doesn't compare
+#               16  -  STDERR verified file doesn't compare
+#
+###############################################################################
+
+sub compareStream {
+    local ($streamFile) = @_;
+    local ($returnVal)  = 0;
+    local ($tempFile)   = "";
+
+    # Check for existence of verified STD stream files
+    if ( !( -e $streamFile ) ) {
+
+        # Display message to user that verified STDOUT file doesn't exist
+        print("        File $streamFile doesn't exist.\n");
+
+        # Set exit value bit 1 to indicate proper failure
+        if ( $streamFile =~ /out$/ ) {
+            $returnVal |= 2;
+        }
+        elsif ( $streamFile =~ /err$/ ) {
+            $returnVal |= 4;
+        }
+    }
+    else {
+
+        # Verified STD stream file exists
+
+        # Create name of the temp file to compare
+        $tempFile = $streamFile;
+        $tempFile =~ s/verified/temp/;
+        $tempFile = $tempFile . ".mod";
+
+        # Perform difference on the STD stream files
+        $diffstdout = `diff $streamFile $tempFile`;
+
+        # Check the return value of the difference
+        if ( $? != 0 ) {
+
+            # Difference of STD stream files failed
+
+            # Check for STDOUT in file name to convey appropirate return value
+            if ( $streamFile =~ /out$/ ) {
+
+                # Display message of the failure of difference to user
+                print("        Failed - STDOUT difference\n$diffstdout\n");
+
+                # Exit value to indicate STDOUT did not compare
+                $returnVal |= 8;
+            }
+            elsif ( $streamFile =~ /err$/ ) {
+
+                # Display message of the failure of difference to user
+                print("        Failed - STDERR difference\n$diffstdout\n");
+
+                # Exit value to indicate STDERR did not compare
+                $returnVal |= 16;
+            }
+        }
+    }
+
+    # Return the result of the compare
+    return ($returnVal);
+}
+
Index: /branches/rel3/psLib/test/sysUtils/.cvsignore
===================================================================
--- /branches/rel3/psLib/test/sysUtils/.cvsignore	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/.cvsignore	(revision 2163)
@@ -0,0 +1,11 @@
+temp
+tst_psAbort
+tst_psError
+tst_psLogMsg
+tst_psMemory
+tst_psStringCopy
+tst_psTrace
+tst_psTrace02_OUT
+tst_psTrace
+core*
+log.txt
Index: /branches/rel3/psLib/test/sysUtils/Makefile
===================================================================
--- /branches/rel3/psLib/test/sysUtils/Makefile	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/Makefile	(revision 2163)
@@ -0,0 +1,49 @@
+################################################################################
+##
+##  Makefile:   test/sysUtils
+##
+##  $Revision: 1.21 $  $Name: not supported by cvs2svn $
+##  $Date: 2004-09-07 21:26:13 $
+##
+##  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+##
+###############################################################################
+
+ifndef prefix
+    export prefix=$(shell cd ../..;pwd)
+endif
+
+include ../../src/Makefile.Globals
+
+CFLAGS := -I../../include $(CFLAGS)
+LDFLAGS := -L../../lib -lpslib -lpstest $(LDFLAGS)
+
+TARGET = tst_psAbort      \
+         tst_psMemory     \
+         tst_psError      \
+         tst_psLogMsg     \
+         tst_psStringCopy \
+         tst_psTrace
+         
+OBJS = $(addsuffix .o,$(TARGET))
+
+all: $(TARGET)
+
+clean:
+	@echo "    Deleting executable and binary files for 'test/collections'"
+	$(RM) $(OBJS)
+
+distclean: clean
+	$(RM) $(TARGET)
+
+install: $(testbindir) $(testbindir)/verified $(TARGET)
+	install $(TARGET) $(testbindir)
+	install verified/*.stderr verified/*.stdout $(testbindir)/verified
+
+$(testbindir):
+	mkdir -p $(testbindir)
+
+$(testbindir)/verified:
+	mkdir -p $(testbindir)/verified
+
+
Index: /branches/rel3/psLib/test/sysUtils/tst_psAbort.c
===================================================================
--- /branches/rel3/psLib/test/sysUtils/tst_psAbort.c	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/tst_psAbort.c	(revision 2163)
@@ -0,0 +1,76 @@
+/** @file  atst_psAbort_01.c
+ *
+ *  @brief Test driver for psAbort function
+ *
+ *  This test drivers contains the following test points for psAbort
+ *     1) Multiple type values in abort message
+ *
+ *  @author  Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.1 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-09-07 21:26:13 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "pslib.h"
+#include "psTest.h"
+
+static int testAbort00(void);
+static int testAbort01(void);
+static int testAbort02(void);
+
+testDescription tests[] = {
+                              {testAbort00, 0, "Multiple type values in abort message", -6, false},
+                              {testAbort01, 1, "String values in abort message", -6, false},
+                              {testAbort02, 2, "Empty strings in abort message", -6, false},
+                              {NULL}
+                          };
+
+int main( int argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psAbort", tests, argc, argv ) );
+}
+
+static int testAbort00(void)
+{
+    int   intval = 1;
+    long  longval = 2;
+    float floatval = 3.01;
+    char  charval = 'E';
+    char  *stringval = "E R R O R";
+
+    // Test point #1 Multiple type values placed in the error string
+    psAbort(__func__,
+            "ALL TYPES intval = %d longval = %ld floatval = %f charval = %c strval = %s",
+            intval, longval, floatval, charval, stringval );
+
+    // Program execution should have ended before this statement but if it
+    // does not return a zero since the expected return value of this test
+    // is a non-zero value
+    return 0;
+}
+
+static int testAbort01(void)
+{
+    // Test point #2 String values in abort message
+    psAbort(PS_STRING(__LINE__), "NO_VALUES");
+
+    // Program execution should have ended before this statement but if it
+    // does not return a zero since the expected return value of this test
+    // is a non-zero value
+    return 0;
+}
+
+static int testAbort02(void)
+{
+    // Test point #2 String values in abort message
+    psAbort("","");
+
+    // Program execution should have ended before this statement but if it
+    // does not return a zero since the expected return value of this test
+    // is a non-zero value
+    return 0;
+}
Index: /branches/rel3/psLib/test/sysUtils/tst_psError.c
===================================================================
--- /branches/rel3/psLib/test/sysUtils/tst_psError.c	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/tst_psError.c	(revision 2163)
@@ -0,0 +1,400 @@
+/** @file  tst_psError.c
+ *
+ *  @brief Test driver for psError function
+ *
+ *  This test driver contains the following test points for psError
+ *     testError00 - psError()                          (Testpoint #486)
+ *     testError01 - psErrorMsg(), psErrorStackPrint()  (Testpoint #725)
+ *     testError02 - psErrorStackPrintV()               (Testpoint #726)
+ *     testError03 - psErrorGet(), psErrorLast()        (Testpoint #727)
+ *     testError04 - psErrorClear()                     (Testpoint #728)
+ *     testError05 - psErrorCodeString()                (Testpoint #729)
+ *
+ *  @author  Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.13 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-10-14 21:14:58 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "pslib.h"
+#include "psTest.h"
+
+static int testError00(void);
+static int testError01(void);
+static int testError02(void);
+static int testError03(void);
+static int testError04(void);
+static int testError05(void);
+static int testErrorRegister(void);
+
+// Function used in testError02 to verify the psErrorStackPrintV function
+static void myErrorStackPrint(FILE *fd,
+                              const char *fmt,
+                              ...)
+{
+    va_list ap;
+
+    // Test whether psErrorStackPrintV() accept a va_list for output variables
+    va_start(ap, fmt);
+    psErrorStackPrintV(fd, fmt, ap);
+    va_end(ap);
+}
+
+testDescription tests[] = {
+                              {testError00, 486, "psError()", 0, false},
+                              {testError01, 725, "psErrorMsg(),psErrorStackPrint()", 0, false},
+                              {testError02, 726, "psErrorStackPrintV()", 0, false},
+                              {testError03, 727, "psErrorGet(),psErrorLast()", 0, false},
+                              {testError04, 728, "psErrorClear()", 0, false},
+                              {testError05, 729, "psErrorCodeString()", 0, false},
+                              {testErrorRegister, 751, "psErrorRegister()", 0, false},
+                              {NULL}
+                          };
+
+int main( int argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( !runTestSuite(stderr, "psError", tests, argc, argv) );
+}
+
+static int testError05(void)
+{
+    psErrorCode code = PS_ERR_BAD_PARAMETER_VALUE;
+
+    // Verify the return value of psErrorCodeString
+    psLogMsg("tst_psError05", PS_LOG_INFO, psErrorCodeString(code));
+
+    // Verify the return value of psErrorCodeString if code is negative
+    if( psErrorCodeString(-1) != NULL) {
+        psLogMsg("tst_psError05", PS_LOG_INFO, "Failed error string with neg. code");
+        return 40;
+    }
+
+    return 0;
+}
+
+static int testError04(void)
+{
+    psErrorCode code = PS_ERR_BAD_PARAMETER_VALUE;
+    psErr *last = NULL;
+    psErr *lastAfterClear = NULL;
+
+    // With an attemp error stack call psErrorClear
+    psErrorClear();
+
+    // Get the last error message and verify PS_ERR_NONE (empty stack)
+    lastAfterClear = psErrorLast();
+    if(lastAfterClear->code != PS_ERR_NONE) {
+        psLogMsg("tst_psError05", PS_LOG_ERROR, "psErrorLast did not return expected.");
+        return 30;
+    }
+    psFree(lastAfterClear);
+
+    // Generate three error messages to have messages on error stack
+    if (psErrorMsg("test4A", code, true, "Error code = %d", code) !=  code) {
+        psLogMsg("tst_psError04", PS_LOG_ERROR, "Failed return value verify.");
+        return 31;
+    }
+    if (psErrorMsg("test4A", (code+1), false, "Error code = %d", (code+1)) != (code+1)) {
+        psLogMsg("tst_psError04", PS_LOG_ERROR, "Failed return value verify.");
+        return 32;
+    }
+    if (psErrorMsg("test4A", (code+2), false, "Error code = %d", (code+2)) != (code+2)) {
+        psLogMsg("tst_psError04", PS_LOG_ERROR, "Failed return value verify.");
+        return 33;
+    }
+
+    // Get the last error message and verify it has the expected code
+    last = psErrorLast();
+    if(last->code != (code+2)) {
+        psLogMsg("tst_psError04", PS_LOG_ERROR, "psErrorLast did not return expected.");
+        return 34;
+    }
+    psFree(last);
+
+    // Clear the error stack
+    psErrorClear();
+
+    // Get the last error message after clear and verify is has PS_ERR_NONE code
+    lastAfterClear = psErrorLast();
+    if(lastAfterClear->code != PS_ERR_NONE) {
+        psLogMsg("tst_psError05", PS_LOG_ERROR, "psErrorLast did not return expected.");
+        return 35;
+    }
+    psFree(lastAfterClear);
+
+    return 0;
+}
+
+static int testError03(void)
+{
+    psErrorCode code = PS_ERR_BAD_PARAMETER_VALUE;
+    psErr *last = NULL;
+    psErr *getErr = NULL;
+
+    // Attempt to get last error message with an empty stack verify psErr with code PS_ERR_NONE
+    last = psErrorLast();
+    if(last->code != PS_ERR_NONE) {
+        psLogMsg("tst_psError03", PS_LOG_ERROR, "psErrorLast did return PS_ERR_NONE for empty stack");
+        return 20;
+    }
+    psFree(last);
+
+    // Attempt to get specific error message with empty stack verify psErr with code PS_ERR_NONE
+    getErr= psErrorGet(2);
+    if(getErr->code != PS_ERR_NONE) {
+        psLogMsg("tst_psError03", PS_LOG_ERROR, "psErrorGet did not return PS_ERR_NONE  for empty stack");
+        return 21;
+    }
+    psFree(getErr);
+
+    // Attempt to get error message with invalid index and an empty stack
+    getErr= psErrorGet(-1);
+    if(getErr->code != PS_ERR_NONE) {
+        psLogMsg("tst_psError03", PS_LOG_ERROR, "psErrorGet with invalid index/empty stack");
+        return 22;
+    }
+    psFree(getErr);
+
+    // Generate three error messages
+    if (psErrorMsg("test3A", code, true, "Error code = %d", code) !=  code) {
+        psLogMsg("tst_psError03", PS_LOG_ERROR, "Failed return value verify.");
+        return 23;
+    }
+    if (psErrorMsg("test3A", (code+1), false, "Error code = %d", (code+1)) != (code+1)) {
+        psLogMsg("tst_psError03", PS_LOG_ERROR, "Failed return value verify.");
+        return 24;
+    }
+    if (psErrorMsg("test3A", (code+2), false, "Error code = %d", (code+2)) != (code+2)) {
+        psLogMsg("tst_psError03", PS_LOG_ERROR, "Failed return value verify.");
+        return 25;
+    }
+
+    last = psErrorLast();
+    getErr= psErrorGet(0);
+
+    // Check that last and get with 0 index are equal
+    if(last != getErr) {
+        psLogMsg("tst_psError03", PS_LOG_ERROR, "psErrorGet(0) not equal to psErrorLast");
+        return 26;
+    }
+    psFree(last);
+
+    // Verify the last error message was returned
+    if ( getErr->code != (code+2) ) {
+        psLogMsg("tst_psError03", PS_LOG_ERROR, "psErrorLast() did not retrieve last error");
+        return 27;
+    }
+    psFree(getErr);
+
+    // Verify the middle error message can be retrieved
+    getErr= psErrorGet(1);
+    if ( getErr->code != (code+1)) {
+        psLogMsg("tst_psError03", PS_LOG_ERROR, "psErrorGet() did not retrieve proper error");
+        return 28;
+    }
+    psFree(getErr);
+
+    // Verify the psErrorGet returns NULL if an invalid index is given
+    getErr= psErrorGet(-1);
+    if ( getErr->code != PS_ERR_NONE ) {
+        psLogMsg("tst_psError03", PS_LOG_ERROR, "psErrorGet() did not return PS_ERR_NONE w/ invalid arg");
+        return 29;
+    }
+    psFree(getErr);
+
+    return 0;
+}
+
+static int testError02(void)
+{
+    psErrorCode code = PS_ERR_BAD_PARAMETER_VALUE;
+
+    // Generate error message and verify return value
+    if (psErrorMsg("test2A", code, true, "Error code = %d", code) != code ) {
+        psLogMsg("tst_psError02", PS_LOG_ERROR, "Failed return value verify.");
+        return 10;
+    }
+    myErrorStackPrint(stderr,"ERROR STACK PRINT Test%dA",2);
+
+    return 0;
+}
+
+static int testError01(void)
+{
+    psErrorCode code=PS_ERR_BAD_PARAMETER_VALUE;
+
+    // Verify the return value of psErrorMsg is the psErrorCode passed
+    if ( psErrorMsg("test1A", code, true, "Error code = %d", code) != code) {
+        psLogMsg("tst_psError01", PS_LOG_ERROR, "Failed return value verify.");
+        return 1;
+    }
+    psErrorStackPrint(stderr,"ERROR STACK PRINT Test1A");
+
+    // test1B empty string in for name argument
+    if ( psErrorMsg("", code+1, true, "Error code = %d", code+1) != code+1) {
+        psLogMsg("tst_psError01", PS_LOG_ERROR, "Failed return with empty string.");
+        return 2;
+    }
+    psErrorStackPrint(stderr,"ERROR STACK PRINT Test1B");
+
+    // test1C null pointer in  for name argument
+    if ( psErrorMsg(NULL, code+2, true, "Error code = %d", code+2) != code+2) {
+        psLogMsg("tst_psError01", PS_LOG_ERROR, "Failed return with null name arg.");
+        return 3;
+    }
+    psErrorStackPrint(stderr,"ERROR STACK PRINT Test1C");
+
+    // test1D undefined code
+    if ( psErrorMsg("test1D", -1, true, "Error code = %d", -1) != -1) {
+        psLogMsg("test_psError01", PS_LOG_ERROR, "Failed return with undefined code.");
+        return 4;
+    }
+    psErrorStackPrint(stderr,"ERROR STACK PRINT Test1D");
+
+    // test1E set psErrorMsg argument to false
+    if( psErrorMsg("test1E", code, false, "Error code = %d", code) != code) {
+        psLogMsg("test_psError01", PS_LOG_ERROR, "Failed return with false new arg.");
+        return 5;
+    }
+    psErrorStackPrint(stderr,"ERROR STACK PRINT Test1E");
+
+    // test1F psErrorMsg with a error code less then PS_ERR_BASE(256)
+    if( psErrorMsg("test1F", 9, true, "Errno code = %d", 9) != 9) {
+        psLogMsg("test_psError01", PS_LOG_ERROR, "Failed return with errno code.");
+        return 6;
+    }
+    psErrorStackPrint(stderr,"ERROR STACK PRINT Test1F");
+
+    return 0;
+}
+
+static int testError00(void)
+{
+
+    int  intval=1;
+    long longval = 2;
+    float floatval = 3.01;
+    char  charval = 'E';
+    char *stringval = "E R R O R";
+
+    // Test point #1 Multiple type values placed in the error string
+    psError(__func__,
+            "ALL TYPES intval = %d longval = %ld floatval = %f charval = %c strval = %s",
+            intval,longval,floatval,charval,stringval);
+
+    // Test point #2 String values in error message
+    psError(PS_STRING(__LINE__),"NO VALUES");
+
+    // Test point #3 Empty strings in error message
+    psError("","");
+
+    return 0;
+}
+
+static int testErrorRegister(void)
+{
+
+    int numErr = 4;
+    psErrorDescription errDesc[] = { {PS_ERR_N_ERR_CLASSES+1,"first"},
+                                     {PS_ERR_N_ERR_CLASSES+2,"second"},
+                                     {PS_ERR_N_ERR_CLASSES+3,"third"},
+                                     {PS_ERR_N_ERR_CLASSES+4,"fourth"} };
+    /*
+        1. invoke psErrorRegister with a n>1 array of psErrorDescriptions. Verify that:
+            a. Each error description given is retrievable with psErrorCodeString.
+    */
+    psErrorRegister(errDesc,numErr);
+
+    for (int i = 0; i < numErr; i++) {
+        const char* desc = psErrorCodeString(PS_ERR_N_ERR_CLASSES+1+i);
+        if (desc == NULL) {
+            psLogMsg(__func__,PS_LOG_ERROR,
+                     "psErrorCode didn't find registered error code.");
+            return 1+i*10;
+        }
+        if (strcmp(desc,errDesc[i].description) != 0) {
+            psLogMsg(__func__,PS_LOG_ERROR,
+                     "psErrorCode didn't return the proper description.  Got '%s', expected '%s'.",
+                     desc,errDesc[i].description);
+            return 2+i*10;
+        }
+    }
+
+    /*
+        2. invoke psErrorCodeString with a static/builtin psLib error code. Verify:
+            a. the result is correct.
+    */
+    const char* desc = psErrorCodeString(PS_ERR_N_ERR_CLASSES);
+    if (desc == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psErrorCode didn't find static error code.");
+        return 40;
+    }
+    if (strcmp(desc,"error classes end marker") != 0) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psErrorCode didn't return the proper description.  Got '%s', expected '%s'.",
+                 desc,"error classes end marker");
+        return 41;
+    }
+
+    desc = psErrorCodeString(PS_ERR_NONE);
+    if (desc == NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psErrorCode didn't find static error code.");
+        return 42;
+    }
+    if (strcmp(desc,"not an error") != 0) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psErrorCode didn't return the proper description.  Got '%s', expected '%s'.",
+                 desc,"not an error");
+        return 43;
+    }
+
+    /*
+        3. invoke psErrorCodeString with an invalid code. Verify a NULL is returned.
+    */
+    desc = psErrorCodeString(PS_ERR_N_ERR_CLASSES+numErr+1);
+    if (desc != NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psErrorCode didn't return a NULL with a bogus input code.");
+        return 44;
+    }
+
+    /*
+        4. invoke psErrorRegister with a NULL psErrorDescription. Verify that:
+            a. the execution does not cease.
+            b. an appropriate error is generated.
+    */
+    psLogMsg(__func__,PS_LOG_INFO,"Following should be an error.");
+    psErrorClear();
+    psErrorRegister(NULL,1);
+    psErr* err = psErrorLast();
+    if (err->code != PS_ERR_BAD_PARAMETER_NULL) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psErrorCode didn't generate proper error code for NULL input.");
+        return 45;
+    }
+    psFree(err);
+
+    /*
+        5. invoke psErrorRegister with nerror=0. Verify that no error occurs.
+    */
+    psErrorClear();
+    psErrorRegister(errDesc,0);
+    err = psErrorLast();
+    if (err->code != PS_ERR_NONE) {
+        psLogMsg(__func__,PS_LOG_ERROR,
+                 "psErrorCode generated an error for nErrors = 0.");
+        return 46;
+    }
+    psFree(err);
+    return 0;
+}
Index: /branches/rel3/psLib/test/sysUtils/tst_psLogMsg.c
===================================================================
--- /branches/rel3/psLib/test/sysUtils/tst_psLogMsg.c	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/tst_psLogMsg.c	(revision 2163)
@@ -0,0 +1,219 @@
+/*****************************************************************************
+    This code will test whether trace levels can be set successfully.
+    This code will test whether trace messages can be displayed with printf
+    style string.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+
+static int testLogMsg00();
+static int testLogMsg01();
+static int testLogMsg02();
+static int testLogMsg03();
+static int testLogMsg04();
+static int testLogMsg05();
+
+testDescription tests[] = {
+                              {
+                                  testLogMsg00, 0, "default log levels, printf-style strings", 0, false
+                              },
+                              {
+                                  testLogMsg01, 1, "default log levels, psVLogMsg()", 0, false
+                              },
+                              {
+                                  testLogMsg02, 2, "psLogSetLevel()", 0, false
+                              },
+                              {
+                                  testLogMsg03, 3, "psLogSetFormat()", 0, false
+                              },
+                              {
+                                  testLogMsg04, 4, "Output Format", 0, false
+                              },
+                              {
+                                  testLogMsg05, 5, "psLogSetDestination()", 0, false
+                              },
+                              {
+                                  NULL
+                              }
+                          };
+
+int main( int argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psLogMsg", tests, argc, argv ) );
+}
+
+
+static void myLogMsg(const char *name,
+                     int level,
+                     const char *fmt,
+                     ...)
+{
+    va_list ap;
+
+    // Test whether psLogMsgV() accept a va_list for output variables.
+    va_start(ap, fmt);
+    psLogMsgV(name, level, fmt, ap);
+    va_end(ap);
+}
+
+static int testLogMsg00()
+{
+    int i = 0;
+
+    // Send a log messages for levels 0:9.  Only the first four messages
+    // should actually be displayed.
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d %f %s\n", i,
+                 (float) i, "beep beep");
+    }
+
+    return 0;
+}
+
+static int testLogMsg01()
+{
+    int i = 0;
+
+    // Send a log messages for levels 0:9.  Only the first four messages
+    // should actually be displayed.
+    for (i=0;i<10;i++) {
+        myLogMsg(__func__, i, "Hello World!  My level is %d %f %s\n", i,
+                 (float) i, "beep beep");
+    }
+
+    return 0;
+}
+
+static int testLogMsg02()
+{
+
+    psLogSetLevel(9);
+    // Send a log messages for levels 0:9.
+    for (int i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    psLogSetLevel(5);
+    psLogMsg(__func__, 6, "This should not be displayed (level %d)\n", 6);
+    psLogSetLevel(4);
+    psLogMsg(__func__, 4, "This should  be displayed (level %d)\n", 4);
+
+    return 0;
+}
+
+static int testLogMsg03()
+{
+    int i;
+
+    fprintf(stderr,"------------- psLogSetFormat() -------------\n");
+    psLogSetFormat("");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    fprintf(stderr,"------------- psLogSetFormat(NULL) -------------\n");
+    psLogSetFormat(NULL);
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    fprintf(stderr,"------------- psLogSetFormat(T) -------------\n");
+    psLogSetFormat("T");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    fprintf(stderr,"------------- psLogSetFormat(H) -------------\n");
+    psLogSetFormat("H");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    fprintf(stderr,"------------- psLogSetFormat(L) -------------\n");
+    psLogSetFormat("L");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    fprintf(stderr,"------------- psLogSetFormat(N) -------------\n");
+    psLogSetFormat("N");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    fprintf(stderr,"------------- psLogSetFormat(M) -------------\n");
+    psLogSetFormat("M");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    fprintf(stderr,"------------- psLogSetFormat(THLNM) -------------\n");
+    psLogSetFormat("THLNM");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    return 0;
+}
+
+
+int testLogMsg04()
+{
+    psLogMsg("Under 15 chars", 0, "Hello World!\n");
+    psLogMsg("This string is more than 15 chars", 0, "Hello World!\n");
+    psLogMsg(__func__, 0, "Line #1\n");
+    psLogMsg(__func__, 0, "Line #2\n");
+    psLogMsg(__func__, 0, "Line #3");
+    psLogMsg(__func__, 0, "Line #4");
+
+    return 0;
+}
+
+int testLogMsg05()
+{
+    int i = 0;
+    FILE* file;
+    char line[256];
+
+    printf("--------------- psLogSetDestination(PS_LOG_NONE) ----------------\n");
+    psLogSetDestination("none");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    printf("------------- psLogSetDestination(PS_LOG_TO_STDERR) -------------\n");
+    psLogSetDestination("dest:stderr");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    printf("------------- psLogSetDestination(PS_LOG_TO_STDOUT) -------------\n");
+    psLogSetDestination("dest:stdout");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+    printf("--------------- psLogSetDestination(""file:log.txt"") ---------------\n");
+    psLogSetDestination("file:log.txt");
+    for (i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World!  My level is %d\n", i);
+    }
+
+    psLogSetDestination("none");
+    printf("--------------------- The Contents of log.txt -------------------\n");
+    file = fopen("log.txt","r");
+    while ( fgets(line,256,file) != NULL ) {
+        printf("%s",line);
+    }
+    fclose(file);
+
+    printf("--------------- psLogSetDestination(""file:/eva/log.txt"") ----------\n");
+    psLogSetDestination("file:/eva/log.txt");
+    for ( i=0;i<10;i++) {
+        psLogMsg(__func__, i, "Hello World! My level is %d\n", i);
+    }
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/sysUtils/tst_psMemory.c
===================================================================
--- /branches/rel3/psLib/test/sysUtils/tst_psMemory.c	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/tst_psMemory.c	(revision 2163)
@@ -0,0 +1,568 @@
+/** @file  tst_psMemory.c
+*
+*  @brief Contains the tests for psMemory.[ch]
+*
+*
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.25 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-09-14 23:55:47 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+// need to allow malloc for callback use
+#define PS_ALLOW_MALLOC 1
+
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <stdlib.h>
+
+
+#include "psTest.h"
+#include "pslib.h"
+
+static int TPFreeReferencedMemory( void );
+static int TPOutOfMemory( void );
+static int TPReallocOutOfMemory( void );
+static void* TPOutOfMemoryExhaustedCallback( size_t size );
+static int TPCheckBufferPositive( void );
+static int TPrealloc( void );
+static int TPallocCallback( void );
+static psMemoryId memAllocateCallback( const psMemBlock *ptr );
+static psMemoryId memFreeCallback( const psMemBlock *ptr );
+static int TPcheckLeaks( void );
+static int TPmemCorruption( void );
+static int TPmultipleFree( void );
+void memProblemCallback( const psMemBlock *ptr, const char *file, int lineno );
+
+static int problemCallbackCalled = 0;
+static int allocCallbackCalled = 0;
+static int freeCallbackCalled = 0;
+static int exhaustedCallbackCalled = 0;
+
+testDescription tests[] = {
+                              {
+                                  TPCheckBufferPositive, 449, "checkBufferPositive", 0, false
+                              },
+                              {
+                                  TPOutOfMemory, 450, "outOfMemory", -6, false
+                              },
+                              {
+                                  TPReallocOutOfMemory, 562, "reallocOutOfMemory", -6, false
+                              },
+                              {
+                                  TPrealloc, 451, "psRealloc", 0, false
+                              },
+                              {
+                                  TPallocCallback, 452, "allocCallback", 0, false
+                              },
+                              {
+                                  TPallocCallback, 453, "allocCallback2", 0, true
+                              },
+                              {
+                                  TPcheckLeaks, 454, "checkLeaks", 0, false
+                              },
+                              {
+                                  TPmemCorruption, 455, "psMemCorruption", 0, false
+                              },
+                              {
+                                  TPFreeReferencedMemory, 456, "freeReferencedMemory", 0, false
+                              },
+                              {
+                                  TPmultipleFree, 699, "multipleFree", 0, false
+                              },
+                              {
+                                  NULL
+                              }
+                          };
+
+int main( int argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psMemory", tests, argc, argv ) );
+}
+
+// Testpoint #449, psAlloc shall allocate memory blocks writeable by caller.
+int TPCheckBufferPositive( void )
+{
+    int * mem;
+    const int size = 100;
+    int failed = 0;
+
+    psLogMsg( __func__, PS_LOG_INFO, "psAlloc shall allocate memory blocks writeable by caller.\n" );
+
+    mem = ( int* ) psAlloc( size * sizeof( int ) );
+    if ( mem == NULL ) {
+        psError( __FILE__, "psAlloc returned a NULL value in %s!", __func__ );
+        return 1;
+    }
+
+    for ( int index = 0;index < size;index++ ) {
+        mem[ index ] = index;
+    }
+
+    for ( int index = 0;index < size;index++ ) {
+        if ( mem[ index ] != index ) {
+            failed++;
+        }
+    }
+
+    psFree( mem );
+
+    return failed;
+}
+
+int TPFreeReferencedMemory( void )
+{
+    // create memory
+    int * mem;
+    int ref = 0;
+
+    psLogMsg( __func__, PS_LOG_INFO, "memory reference count shall be incrementable/decrementable" );
+
+    mem = ( int* ) psAlloc( 100 * sizeof( int ) );
+
+    ref = psMemGetRefCounter( mem );
+    if ( ref != 1 ) {
+        psError( __func__, "Expected to buffer reference count to be initially 1, but it was %d.", ref );
+        return 1;
+    }
+
+    psMemIncrRefCounter( mem );
+    psMemIncrRefCounter( mem );
+    psMemIncrRefCounter( mem );
+
+    ref = psMemGetRefCounter( mem );
+    if ( ref != 4 ) {
+        psError( __func__, "Expected to find buffer reference count to be 4, but it was %d.", ref );
+        return 1;
+    }
+
+    psMemDecrRefCounter( mem );
+    psMemDecrRefCounter( mem );
+
+    ref = psMemGetRefCounter( mem );
+    if ( ref != 2 ) {
+        psError( __func__, "Expected to find buffer reference count to be 2, but it was %d.", ref );
+        return 1;
+    }
+
+    psLogMsg( __func__, PS_LOG_INFO, "psFree shall be just decrement a multiple refererenced pointer." );
+
+    psFree( mem );
+
+    ref = psMemGetRefCounter( mem );
+    if ( ref != 1 ) {
+        psError( __func__, "Expected to find buffer reference count to be 1, but it was %d.", ref );
+        return 1;
+    }
+
+    psFree( mem );
+
+    return 0;
+}
+
+// Bug/Task #562 regression test.  Upon requesting more memory than is available, psRealloc shall call
+// the psMemExhaustedCallback.
+int TPReallocOutOfMemory( void )
+{
+    int * mem[ 100 ];
+    psMemExhaustedCallback cb;
+
+    for ( int lcv = 0; lcv < 100; lcv++ ) {
+        mem[ lcv ] = NULL;
+    }
+
+    psLogMsg( __func__, PS_LOG_INFO, "Upon requesting more memory than is available, psRealloc shall call "
+              "the psMemExhaustedCallback.\n" );
+
+    exhaustedCallbackCalled = 0;
+
+    cb = psMemExhaustedCallbackSet( TPOutOfMemoryExhaustedCallback );
+
+    for ( int lcv = 0; lcv < 100; lcv++ ) {
+        mem[ lcv ] = ( int* ) psAlloc( 10 );
+    }
+
+    for ( int lcv = 0; lcv < 100; lcv++ ) {
+        mem[ lcv ] = ( int* ) psRealloc( mem[ lcv ], SIZE_MAX/2 - 1000 );
+    }
+
+    psMemExhaustedCallbackSet( cb );
+
+    if ( exhaustedCallbackCalled == 0 ) {
+        psError( __FILE__, "Called psRealloc with HUGE memory requirement and survived in %s!", __func__ );
+        return 1;
+    }
+
+    for ( int lcv = 0; lcv < 100; lcv++ ) {
+        psFree( mem[ lcv ] );
+    }
+
+    return 0;
+}
+// Testpoint #450,  Upon requesting more memory than is available, psalloc shall call
+// the psMemExhaustedCallback.
+int TPOutOfMemory( void )
+{
+    int * mem[ 100 ];
+    psMemExhaustedCallback cb;
+
+    for ( int lcv = 0; lcv < 100; lcv++ ) {
+        mem[ lcv ] = NULL;
+    }
+
+    psLogMsg( __func__, PS_LOG_INFO, "Upon requesting more memory than is available, psalloc shall call "
+              "the psMemExhaustedCallback.\n" );
+
+    exhaustedCallbackCalled = 0;
+
+    cb = psMemExhaustedCallbackSet( TPOutOfMemoryExhaustedCallback );
+
+    for ( int lcv = 0; lcv < 100; lcv++ ) {
+        mem[ lcv ] = ( int* ) psAlloc( SIZE_MAX/2 - 1000 );
+    }
+
+    psMemExhaustedCallbackSet( cb );
+
+    if ( exhaustedCallbackCalled == 0 ) {
+        psError( __FILE__, "Called psAlloc with HUGE memory requirement and survived in %s!", __func__ );
+        return 1;
+    }
+
+    for ( int lcv = 0; lcv < 100; lcv++ ) {
+        psFree( mem[ lcv ] );
+    }
+
+    return 0;
+}
+
+// Testpoint #451,  psRealloc shall increase/decrease memory buffer while preserving contents
+int TPrealloc( void )
+{
+    int * mem1;
+    int* mem2;
+    int* mem3;
+    const int initialSize = 100;
+
+    psLogMsg( __func__, PS_LOG_INFO, "psRealloc shall increase/decrease memory buffer while "
+              "preserving contents" );
+
+    // allocate buffer with known values.
+    mem1 = ( int* ) psAlloc( initialSize * sizeof( int ) );
+    mem2 = ( int* ) psAlloc( initialSize * sizeof( int ) );
+    mem3 = ( int* ) psAlloc( initialSize * sizeof( int ) );
+    for ( int lcv = 0;lcv < initialSize;lcv++ ) {
+        mem1[ lcv ] = mem2[ lcv ] = mem3[ lcv ] = lcv;
+    }
+
+    psMemCheckCorruption( 1 );
+    psLogMsg( __func__, PS_LOG_INFO, "Expanding memory buffer." );
+
+    // realloc to 2x
+    mem1 = ( int* ) psRealloc( mem1, 2 * initialSize * sizeof( int ) );
+    mem2 = ( int* ) psRealloc( mem2, 2 * initialSize * sizeof( int ) );
+    mem3 = ( int* ) psRealloc( mem3, 2 * initialSize * sizeof( int ) );
+
+    // check values of initial block
+    for ( int i = 0;i < initialSize;i++ ) {
+        if ( mem1[ i ] != i || mem2[ i ] != i || mem3[ i ] != i ) {
+            psError( __FILE__, "Realloc didn't preserve the contents with expanding buffer in %s.",
+                     __func__ );
+            break;
+        }
+    }
+
+    psMemCheckCorruption( 1 );
+    psLogMsg( __func__, PS_LOG_INFO, "Shrinking memory buffer." );
+
+    // realloc to 1/2 initial value.
+    mem1 = ( int* ) psRealloc( mem1, ( initialSize / 2 ) * sizeof( int ) );
+    mem2 = ( int* ) psRealloc( mem2, ( initialSize / 2 ) * sizeof( int ) );
+    mem3 = ( int* ) psRealloc( mem3, ( initialSize / 2 ) * sizeof( int ) );
+
+    // check values of initial block
+    for ( int i = 0;i < initialSize / 2;i++ ) {
+        if ( mem1[ i ] != i || mem2[ i ] != i || mem3[ i ] != i ) {
+            psError( __FILE__, "Realloc didn't preserve the contents with shrinking buffer in %s.",
+                     __func__ );
+            break;
+        }
+    }
+
+    psFree( mem1 );
+    psFree( mem2 );
+    psFree( mem3 );
+
+    return 0;
+}
+
+int TPallocCallback( void )
+{
+    int * mem1;
+    int* mem2;
+    int* mem3;
+    int currentId = psMemGetId();
+    const int initialSize = 100;
+    int mark;
+
+    allocCallbackCalled = 0;
+    freeCallbackCalled = 0;
+    psMemAllocateCallbackSet( memAllocateCallback );
+    psMemFreeCallbackSet( memFreeCallback );
+
+    psMemAllocateCallbackSetID( currentId + 1 );
+    psMemFreeCallbackSetID( currentId + 1 );
+
+    psLogMsg( __func__, PS_LOG_INFO, "call to psAlloc/psRealloc shall generate a callback if specified "
+              "memory ID is allocated." );
+
+    // allocate buffer with known values.
+    mem1 = ( int* ) psAlloc( initialSize * sizeof( int ) );
+    mem2 = ( int* ) psAlloc( initialSize * sizeof( int ) );
+    mem3 = ( int* ) psAlloc( initialSize * sizeof( int ) );
+
+    psFree( mem1 );
+    psFree( mem2 );
+    psFree( mem3 );
+
+    if ( allocCallbackCalled != 2 || freeCallbackCalled != 2 ) {
+        psError( __FILE__, "alloc/free callbacks were not called the proper number of times in %s",
+                 __func__ );
+        return 1;
+    }
+
+    allocCallbackCalled = 0;
+    freeCallbackCalled = 0;
+
+    mark = psMemGetId();
+
+    mem1 = ( int* ) psAlloc( initialSize * sizeof( int ) );
+
+    psMemAllocateCallbackSetID( mark );
+
+    mem1 = ( int* ) psRealloc( mem1, initialSize * 2 * sizeof( int ) );
+
+    psFree( mem1 );
+
+    if ( allocCallbackCalled != 2 ) {
+        psError( __FILE__, "realloc callbacks were not called the proper number of times in %s",
+                 __func__ );
+        return 1;
+    }
+
+    return 0;
+
+}
+
+int TPcheckLeaks( void )
+{
+    const int numBuffers = 5;
+    int* buffers[ 5 ];
+    int lcv;
+    int currentId = psMemGetId();
+    psMemBlock** blks;
+    int nLeaks = 0;
+    int lineMark = 0;
+
+    psLogMsg( __func__, PS_LOG_INFO, "psMemCheckLeaks shall return the number of blocks above an ID "
+              "that are still allocated" );
+
+    for ( lcv = 0;lcv < numBuffers;lcv++ ) {
+        lineMark = __LINE__ + 1;
+        buffers[ lcv ] = psAlloc( sizeof( int ) );
+    }
+
+    for ( lcv = 1;lcv < numBuffers;lcv++ ) {
+        psFree( buffers[ lcv ] );
+    }
+
+    psLogMsg( __func__, PS_LOG_INFO, "following psMemCheckLeaks call should produce one instance." );
+
+    nLeaks = psMemCheckLeaks( currentId, &blks, stderr );
+
+    if ( nLeaks != 1 ) {
+        psError( __FILE__, "psMemCheckLeaks should have found 1 leak, but found %d in %s.", nLeaks, __func__ );
+        return 1;
+    }
+
+    if ( blks[ 0 ] ->lineno != lineMark ) {
+        psError( __FILE__, "psMemCheckLeaks found a leak other than the expected one (line %d vs %d) in %s.",
+                 lineMark, blks[ 0 ] ->lineno, __func__ );
+        return 1;
+    }
+
+    psFree( buffers[ 0 ] );
+    psFree( blks );
+
+    psLogMsg( __func__, PS_LOG_INFO, "Testing psMemCheckLeaks again with a different leak location" );
+    psMemCheckLeaks(currentId,NULL,stderr);
+
+    for ( lcv = 0;lcv < numBuffers;lcv++ ) {
+        lineMark = __LINE__ + 1;
+        buffers[ lcv ] = psAlloc( sizeof( int ) );
+    }
+
+    for ( lcv = 0;lcv < numBuffers - 1;lcv++ ) {
+        psFree( buffers[ lcv ] );
+    }
+
+    psLogMsg( __func__, PS_LOG_INFO, "following psMemCheckLeaks call should produce one error." );
+
+    nLeaks = psMemCheckLeaks( currentId, &blks, stderr );
+
+    if ( nLeaks != 1 ) {
+        psError( __FILE__, "psMemCheckLeaks should have found 1 leak, but found %d in %s.", nLeaks, __func__ );
+        return 1;
+    }
+
+    if ( blks[ 0 ] ->lineno != lineMark ) {
+        psError( __FILE__, "psMemCheckLeaks found a leak other than the expected one in %s.", __func__ );
+        return 1;
+    }
+
+    psFree( buffers[ 4 ] );
+    psFree( blks );
+
+    psLogMsg( __func__, PS_LOG_INFO, "Testing psMemCheckLeaks again with multiple leak locations." );
+
+    for ( lcv = 0;lcv < numBuffers;lcv++ ) {
+        lineMark = __LINE__ + 1;
+        buffers[ lcv ] = psAlloc( sizeof( int ) );
+    }
+
+    for ( lcv = 0;lcv < numBuffers;lcv++ ) {
+        if ( lcv % 2 == 0 ) {
+            psFree( buffers[ lcv ] );
+        }
+    }
+
+    psLogMsg( __func__, PS_LOG_INFO, "following psMemCheckLeaks call should produce two errors." );
+
+    nLeaks = psMemCheckLeaks( currentId, &blks, stderr );
+
+    if ( nLeaks != 2 ) {
+        psError( __FILE__, "psMemCheckLeaks should have found 1 leak, but found %d in %s.", nLeaks, __func__ );
+        return 1;
+    }
+
+    if ( blks[ 0 ] ->lineno != lineMark ) {
+        psError( __FILE__, "psMemCheckLeaks found a leak other than the expected one in %s.", __func__ );
+        return 1;
+    }
+
+    psFree( blks );
+    psFree( buffers[ 1 ] );
+    psFree( buffers[ 3 ] );
+
+    return 0;
+}
+
+int TPmemCorruption( void )
+{
+    int * buffer = NULL;
+    int oldValue = 0;
+    int corruptions = 0;
+    psMemProblemCallback cb;
+
+    psLogMsg( __func__, PS_LOG_INFO, "psMemCheckCorruption shall detect memory corruptions" );
+
+    buffer = psAlloc( sizeof( int ) );
+
+    // cause memory corruption via buffer underflow
+    *buffer = 1;
+    buffer--;
+    oldValue = *buffer;
+    *buffer = 2;
+
+    problemCallbackCalled = 0;
+    cb = psMemProblemCallbackSet( memProblemCallback );
+
+    psLogMsg( __func__, PS_LOG_INFO, "psMemCheckCorruption should output an error message and "
+              "memProblemCallback callback should be called." );
+
+    corruptions = psMemCheckCorruption( 0 );
+
+    // restore the memory problem callback
+    psMemProblemCallbackSet( cb );
+
+    // restore the value, 'uncorrupting' the buffer
+    *buffer = oldValue;
+    buffer++;
+
+    psFree( buffer );
+
+    if ( corruptions != 1 ) {
+        psError( __FILE__, "Expected one memory corruption but found %d in %s.",
+                 corruptions, __func__ );
+        return 1;
+    }
+
+    if ( problemCallbackCalled != 1 ) {
+        psError( __FILE__, "The memProblemCallback was not invoked but should have been in %s",
+                 __func__ );
+        return 1;
+    }
+
+    return 0;
+
+}
+
+void memProblemCallback( const psMemBlock *ptr, const char *file, int lineno )
+{
+    psLogMsg( __func__, PS_LOG_INFO, "memory callback called for id %d (%s:%d).",
+              ptr->id, file, lineno );
+    problemCallbackCalled++;
+    return ;
+}
+
+psMemoryId memAllocateCallback( const psMemBlock *ptr )
+{
+    psLogMsg( __func__, PS_LOG_INFO, "block %d was (re)allocated", ptr->id );
+    allocCallbackCalled++;
+    return 1;
+}
+
+psMemoryId memFreeCallback( const psMemBlock *ptr )
+{
+    psLogMsg( __func__, PS_LOG_INFO, "block %d was freed", ptr->id );
+    freeCallbackCalled++;
+    return 1;
+}
+
+void* TPOutOfMemoryExhaustedCallback( size_t size )
+{
+    psLogMsg( __func__, PS_LOG_INFO, "Custom MemExhaustedCallback was invoked." );
+    exhaustedCallbackCalled++;
+    return NULL;
+}
+
+int TPmultipleFree( void )
+{
+
+    void * buffer = psAlloc( 1024 );
+
+    psFree( buffer );
+
+    psLogMsg( __func__, PS_LOG_INFO, "Next should be an error about multiple freeing." );
+    psFree( buffer );
+
+    psErr* err = (psErr*)psErrorLast();
+
+    if (err->code != PS_ERR_MEMORY_DEREF_USAGE) {
+        psErrorMsg("psLibTest.sysUtils.tst_psMemory",PS_ERR_UNKNOWN,true,
+                   "Multiple psFree calls generated wrong error code (%d)",
+                   err->code);
+        psFree(err);
+        return 1;
+    }
+
+    psFree(err);
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/sysUtils/tst_psString.c
===================================================================
--- /branches/rel3/psLib/test/sysUtils/tst_psString.c	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/tst_psString.c	(revision 2163)
@@ -0,0 +1,250 @@
+/** @file  tst_psString.c
+ *
+ *  @brief Test driver for psStringCopy functions
+ *
+ *  This test driver contains the following test points for psStringCopy
+ *  and psStringNCopy functions.
+ *    1) Verify string copy - psStringCopy
+ *    2) Verify empty string copy - psStringCopy
+ *    3) Verify string copy with length - psStringNCopy
+ *    4) Verify empty string copy with length - psStringNCopy
+ *    5) Copy string to larger string - psStringNCopy
+ *    6) Copy string with negative size - psStringNCopy
+ *    7) Verifiy creation of string literal - PS_STRING
+ *
+ *  Return:   Number of test points which failed
+ *
+ *  @author  Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.9 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-10-06 01:59:08 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include <string.h>
+#include "pslib.h"
+#include "psTest.h"
+
+static int testStringCopy00(void);
+static int testStringCopy01(void);
+static int testStringCopy02(void);
+static int testStringCopy03(void);
+static int testStringCopy04(void);
+static int testStringCopy05(void);
+static int testStringCopy06(void);
+
+testDescription tests[] = {
+                              {testStringCopy00, 0, "Verify string copy", 0, false},
+                              {testStringCopy01, 1, "Verify empty string copy", 0, false},
+                              {testStringCopy02, 2, "Verify string copy with length", 0, false},
+                              {testStringCopy03, 3, "Verify empty string copy with length", 0, false},
+                              {testStringCopy04, 4, "Copy string to larger string", 0, false},
+                              {testStringCopy05, 5, "Copy string with negative size", 0, false},
+                              {testStringCopy06, 6, "Verify creation of string literal", 0, false},
+                              {NULL}
+                          };
+
+int main( int argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psString", tests, argc, argv ) );
+}
+
+/*
+int main( int argc,
+          char * argv[] )
+{
+    bool  tpResult = false;
+    char  stringval[20] = "E R R O R";
+    char  stringval1[20] = "e r r o r";
+    char  *stringvalnocopy = "F A I L";
+    char  *substringval = "e r r";
+    int   substringlen = 6;
+    char  *emptyval = "";
+    int   tpFails = 0;
+    char  *strResult;
+    int   increaseSize = 5;
+    int   negativeSize = -5;
+    int   result = 0;
+    int   result1 = 0;
+    int   memBlockAllocated = 0;
+    psMemBlock ***memBlockPtr = NULL;
+ 
+*/
+
+static int testStringCopy00(void)
+{
+    char  stringval[20] = "E R R O R";
+    int   result = 0;
+    int   result1 = 0;
+    char  *strResult;
+
+    // Test point #1 Verify string copy - psStringCopy
+    strResult = psStringCopy(stringval);
+    // Perform string compare
+    result = strcmp(strResult, stringval);
+    // Modify original string
+    stringval[0]='G';
+    result1 = strcmp(strResult, stringval);
+    stringval[0]='E';
+    if ( ( result != 0 ) || ( result1 == 0) ) {
+        fprintf(stderr, "Failed test point #1 strcmp result = %d expected 0\n",result);
+        fprintf(stderr, "                               src = %s expected %s\n",
+                strResult, stringval);
+        fprintf(stderr, "             changed strcmp result = %d expected 1\n",result1);
+        fprintf(stderr, "             changed           src = %s expected %s\n",strResult,
+                stringval);
+        return 1;
+    }
+
+    // Free memory allocated
+    psFree(strResult);
+
+    return 0;
+}
+
+static int testStringCopy01(void)
+{
+    char  *emptyval = "";
+    int   result = 0;
+    char  *strResult;
+
+    // Test point #2 Verify empty string copy - psStringCopy
+    strResult = psStringCopy(emptyval);
+    // Perform string compare
+    result = strcmp(strResult, emptyval);
+    if ( result != 0 ) {
+        fprintf(stderr,"Failed test point #2 strcmp result = %d expected 0\n",result);
+        fprintf(stderr,"                               src = %s expected %s\n",
+                strResult, emptyval);
+        return 1;
+    }
+
+    // Free memory allocated
+    psFree(strResult);
+
+    return 0;
+}
+
+static int testStringCopy02(void)
+{
+    int   result = 0;
+    int   result1 = 0;
+    char  *strResult;
+    char  stringval1[20] = "e r r o r";
+    int   substringlen = 5;
+    char  *substringval = "e r r";
+
+    // Test point #3 Verify string copy with length - psStringNCopy
+    strResult = psStringNCopy(stringval1, substringlen);
+    // Perform string compare and get string length
+    result = strncmp(strResult, substringval, substringlen);
+    // Change original string
+    stringval1[0] = 'g';
+    result1 = strncmp(strResult, substringval, substringlen);
+    if ( ( result != 0 ) || ( result1 != 0 ) ) {
+        fprintf(stderr,"Failed test point #3 strcmp result = %d expected 0\n",result);
+        fprintf(stderr,"                               src = %s expected %s\n",
+                strResult, substringval);
+        fprintf(stderr,"             changed strcmp result = %d expected 0\n",result1);
+        fprintf(stderr,"                               src = %s expected %s\n",
+                strResult, substringval);
+        return 1;
+    }
+    // Free memory allocated
+    psFree(strResult);
+
+    return 0;
+}
+
+static int testStringCopy03(void)
+{
+    int   result = 0;
+    int   result1 = 0;
+    char  *strResult;
+    char  *stringvalnocopy = "F A I L";
+
+    // Test point #4 Verify empty string copy with length - psStringNCopy
+    strResult = psStringNCopy(stringvalnocopy, 0);
+    // Perform string compare and get sting length
+    result = strcmp(strResult, stringvalnocopy);
+    result1 = strlen(strResult);
+    if ( result == 0 ) {
+        fprintf(stderr,"Failed test point #4 strcmp result = %d didn't expected %d\n",result,0);
+        fprintf(stderr,"                               src = %s didn't expected %s\n",
+                strResult, stringvalnocopy);
+        return 1;
+    }
+    // Free memory
+    psFree(strResult);
+
+    return 0;
+}
+
+static int testStringCopy04(void)
+{
+    int   result = 0;
+    int   result1 = 0;
+    char  *strResult;
+    char  stringval[20] = "E R R O R";
+    int   increaseSize = 5;
+
+    // Test point #5 Copy string to larger string - psStringNCopy
+    strResult = psStringNCopy(stringval, (strlen(stringval) + increaseSize));
+    // Perform string compare and get string length
+    result = strcmp(strResult, stringval);
+    result1 = strlen(strResult);
+    // The strings should still compare
+    if ( ( result != 0 ) ||
+            ( result1 != strlen(stringval) ) ) {
+        fprintf(stderr,"Failed test point #5 strcmp result = %d expected %d\n",result,0);
+        fprintf(stderr,"                               src = %s expected %s\n",
+                strResult, stringval);
+        fprintf(stderr,"                     strlne result = %d expected %d\n",result1,
+                (int)strlen(stringval));
+        return 1;
+    }
+    // Free memory
+    psFree(strResult);
+
+    return 0;
+}
+
+static int testStringCopy05(void)
+{
+    char  *strResult;
+    char  stringval[20] = "E R R O R";
+    int   negativeSize = -5;
+
+    // Test point #6 Copy string with negative size - psStringNCopy
+    strResult = psStringNCopy(stringval, negativeSize);
+    if ( strResult != NULL ) {
+        fprintf(stderr,"Failed test point #6 return value = %ld expected NULL\n",
+                (unsigned long)strResult);
+        return 1;
+    }
+    // Memory should not have been allocated
+
+    return 0;
+}
+
+static int testStringCopy06(void)
+{
+    char  *strResult;
+    char  stringval[20] = "E R R O R";
+    int   result = 0;
+
+    // Test point #7 Verify creation of string literal - PS_STRING
+    strResult = PS_STRING(E R R O R);
+    result = strcmp(strResult, stringval);
+    if ( result != 0 ) {
+        fprintf(stderr,"Failed test point #7 strcmp result = %d expected %d",result,0);
+        return 1;
+    }
+    // Memory should not have been allocated
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/sysUtils/tst_psStringCopy.c
===================================================================
--- /branches/rel3/psLib/test/sysUtils/tst_psStringCopy.c	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/tst_psStringCopy.c	(revision 2163)
@@ -0,0 +1,250 @@
+/** @file  tst_psString.c
+ *
+ *  @brief Test driver for psStringCopy functions
+ *
+ *  This test driver contains the following test points for psStringCopy
+ *  and psStringNCopy functions.
+ *    1) Verify string copy - psStringCopy
+ *    2) Verify empty string copy - psStringCopy
+ *    3) Verify string copy with length - psStringNCopy
+ *    4) Verify empty string copy with length - psStringNCopy
+ *    5) Copy string to larger string - psStringNCopy
+ *    6) Copy string with negative size - psStringNCopy
+ *    7) Verifiy creation of string literal - PS_STRING
+ *
+ *  Return:   Number of test points which failed
+ *
+ *  @author  Eric Van Alst, MHPCC
+ *
+ *  @version $Revision: 1.9 $  $Name: not supported by cvs2svn $
+ *  @date  $Date: 2004-10-06 01:59:08 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#include <string.h>
+#include "pslib.h"
+#include "psTest.h"
+
+static int testStringCopy00(void);
+static int testStringCopy01(void);
+static int testStringCopy02(void);
+static int testStringCopy03(void);
+static int testStringCopy04(void);
+static int testStringCopy05(void);
+static int testStringCopy06(void);
+
+testDescription tests[] = {
+                              {testStringCopy00, 0, "Verify string copy", 0, false},
+                              {testStringCopy01, 1, "Verify empty string copy", 0, false},
+                              {testStringCopy02, 2, "Verify string copy with length", 0, false},
+                              {testStringCopy03, 3, "Verify empty string copy with length", 0, false},
+                              {testStringCopy04, 4, "Copy string to larger string", 0, false},
+                              {testStringCopy05, 5, "Copy string with negative size", 0, false},
+                              {testStringCopy06, 6, "Verify creation of string literal", 0, false},
+                              {NULL}
+                          };
+
+int main( int argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psString", tests, argc, argv ) );
+}
+
+/*
+int main( int argc,
+          char * argv[] )
+{
+    bool  tpResult = false;
+    char  stringval[20] = "E R R O R";
+    char  stringval1[20] = "e r r o r";
+    char  *stringvalnocopy = "F A I L";
+    char  *substringval = "e r r";
+    int   substringlen = 6;
+    char  *emptyval = "";
+    int   tpFails = 0;
+    char  *strResult;
+    int   increaseSize = 5;
+    int   negativeSize = -5;
+    int   result = 0;
+    int   result1 = 0;
+    int   memBlockAllocated = 0;
+    psMemBlock ***memBlockPtr = NULL;
+ 
+*/
+
+static int testStringCopy00(void)
+{
+    char  stringval[20] = "E R R O R";
+    int   result = 0;
+    int   result1 = 0;
+    char  *strResult;
+
+    // Test point #1 Verify string copy - psStringCopy
+    strResult = psStringCopy(stringval);
+    // Perform string compare
+    result = strcmp(strResult, stringval);
+    // Modify original string
+    stringval[0]='G';
+    result1 = strcmp(strResult, stringval);
+    stringval[0]='E';
+    if ( ( result != 0 ) || ( result1 == 0) ) {
+        fprintf(stderr, "Failed test point #1 strcmp result = %d expected 0\n",result);
+        fprintf(stderr, "                               src = %s expected %s\n",
+                strResult, stringval);
+        fprintf(stderr, "             changed strcmp result = %d expected 1\n",result1);
+        fprintf(stderr, "             changed           src = %s expected %s\n",strResult,
+                stringval);
+        return 1;
+    }
+
+    // Free memory allocated
+    psFree(strResult);
+
+    return 0;
+}
+
+static int testStringCopy01(void)
+{
+    char  *emptyval = "";
+    int   result = 0;
+    char  *strResult;
+
+    // Test point #2 Verify empty string copy - psStringCopy
+    strResult = psStringCopy(emptyval);
+    // Perform string compare
+    result = strcmp(strResult, emptyval);
+    if ( result != 0 ) {
+        fprintf(stderr,"Failed test point #2 strcmp result = %d expected 0\n",result);
+        fprintf(stderr,"                               src = %s expected %s\n",
+                strResult, emptyval);
+        return 1;
+    }
+
+    // Free memory allocated
+    psFree(strResult);
+
+    return 0;
+}
+
+static int testStringCopy02(void)
+{
+    int   result = 0;
+    int   result1 = 0;
+    char  *strResult;
+    char  stringval1[20] = "e r r o r";
+    int   substringlen = 5;
+    char  *substringval = "e r r";
+
+    // Test point #3 Verify string copy with length - psStringNCopy
+    strResult = psStringNCopy(stringval1, substringlen);
+    // Perform string compare and get string length
+    result = strncmp(strResult, substringval, substringlen);
+    // Change original string
+    stringval1[0] = 'g';
+    result1 = strncmp(strResult, substringval, substringlen);
+    if ( ( result != 0 ) || ( result1 != 0 ) ) {
+        fprintf(stderr,"Failed test point #3 strcmp result = %d expected 0\n",result);
+        fprintf(stderr,"                               src = %s expected %s\n",
+                strResult, substringval);
+        fprintf(stderr,"             changed strcmp result = %d expected 0\n",result1);
+        fprintf(stderr,"                               src = %s expected %s\n",
+                strResult, substringval);
+        return 1;
+    }
+    // Free memory allocated
+    psFree(strResult);
+
+    return 0;
+}
+
+static int testStringCopy03(void)
+{
+    int   result = 0;
+    int   result1 = 0;
+    char  *strResult;
+    char  *stringvalnocopy = "F A I L";
+
+    // Test point #4 Verify empty string copy with length - psStringNCopy
+    strResult = psStringNCopy(stringvalnocopy, 0);
+    // Perform string compare and get sting length
+    result = strcmp(strResult, stringvalnocopy);
+    result1 = strlen(strResult);
+    if ( result == 0 ) {
+        fprintf(stderr,"Failed test point #4 strcmp result = %d didn't expected %d\n",result,0);
+        fprintf(stderr,"                               src = %s didn't expected %s\n",
+                strResult, stringvalnocopy);
+        return 1;
+    }
+    // Free memory
+    psFree(strResult);
+
+    return 0;
+}
+
+static int testStringCopy04(void)
+{
+    int   result = 0;
+    int   result1 = 0;
+    char  *strResult;
+    char  stringval[20] = "E R R O R";
+    int   increaseSize = 5;
+
+    // Test point #5 Copy string to larger string - psStringNCopy
+    strResult = psStringNCopy(stringval, (strlen(stringval) + increaseSize));
+    // Perform string compare and get string length
+    result = strcmp(strResult, stringval);
+    result1 = strlen(strResult);
+    // The strings should still compare
+    if ( ( result != 0 ) ||
+            ( result1 != strlen(stringval) ) ) {
+        fprintf(stderr,"Failed test point #5 strcmp result = %d expected %d\n",result,0);
+        fprintf(stderr,"                               src = %s expected %s\n",
+                strResult, stringval);
+        fprintf(stderr,"                     strlne result = %d expected %d\n",result1,
+                (int)strlen(stringval));
+        return 1;
+    }
+    // Free memory
+    psFree(strResult);
+
+    return 0;
+}
+
+static int testStringCopy05(void)
+{
+    char  *strResult;
+    char  stringval[20] = "E R R O R";
+    int   negativeSize = -5;
+
+    // Test point #6 Copy string with negative size - psStringNCopy
+    strResult = psStringNCopy(stringval, negativeSize);
+    if ( strResult != NULL ) {
+        fprintf(stderr,"Failed test point #6 return value = %ld expected NULL\n",
+                (unsigned long)strResult);
+        return 1;
+    }
+    // Memory should not have been allocated
+
+    return 0;
+}
+
+static int testStringCopy06(void)
+{
+    char  *strResult;
+    char  stringval[20] = "E R R O R";
+    int   result = 0;
+
+    // Test point #7 Verify creation of string literal - PS_STRING
+    strResult = PS_STRING(E R R O R);
+    result = strcmp(strResult, stringval);
+    if ( result != 0 ) {
+        fprintf(stderr,"Failed test point #7 strcmp result = %d expected %d",result,0);
+        return 1;
+    }
+    // Memory should not have been allocated
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/sysUtils/tst_psTrace.c
===================================================================
--- /branches/rel3/psLib/test/sysUtils/tst_psTrace.c	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/tst_psTrace.c	(revision 2163)
@@ -0,0 +1,361 @@
+/*****************************************************************************
+    This code will test whether trace levels can be set successfully.
+ 
+    XXX: For the last two testpoints, must verify that the results are
+    correct, and put that verification in the test as well.
+ *****************************************************************************/
+#include <stdio.h>
+#include "pslib.h"
+#include "psTest.h"
+
+
+static int testTrace00(void);
+static int testTrace01(void);
+static int testTrace02(void);
+static int testTrace03(void);
+static int testTrace04(void);
+static int testTrace05(void);
+static int testTrace05a(void);
+static int testTrace06(void);
+static int testTrace08(void);
+
+testDescription tests[] = {
+                              {testTrace00, 0, "psTraceSetLevel() and psTraceGetLevel()", 0, false},
+                              {testTrace01, 1, "psTraceSetLevel(): set multiple components in one call", 0, false},
+                              {testTrace02, 2, "psTraceSetLevel(): test static inheritance", 0, false},
+                              {testTrace03, 3, "psTraceReset()", 0, false},
+                              {testTrace04, 4, "psTrace()", 0, false},
+                              {testTrace05, 5, "psTracePrintLevels()", 0, false},
+                              {testTrace05a, 5, "optional leading dot and psTracePrintLevels()", 0, false},
+                              {testTrace06, 6, "Testing psTraceReset", 0, false},
+                              {testTrace08, 8, "Testing ", 0, false},
+                              {NULL}
+                          };
+
+testDescription tests2[] = {
+                               {testTrace08, 8, "Testing ", 0, false},
+                           };
+
+int main( int argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+
+    return ( ! runTestSuite( stderr, "psTrace", tests, argc, argv ) );
+}
+
+static int testTrace00(void)
+{
+    int i;
+    int lev = 0;
+
+    psTraceSetDestination(stderr);
+
+    for (i=0;i<10;i++) {
+        (void)psTraceSetLevel(".", i);
+        lev = psTraceGetLevel(".");
+        if (lev != i) {
+            fprintf(stderr,"ERROR: (.) expected trace level was %d, actual was %d\n",
+                    i, lev);
+            return 1;
+        }
+    }
+    (void)psTraceSetLevel(".", 3);
+
+    for (i=5;i<10;i++) {
+        (void)psTraceSetLevel(".NODE00", i);
+        lev = psTraceGetLevel(".NODE00");
+        if (lev != i) {
+            fprintf(stderr,"ERROR: (.NODE00) expected trace level was %d, actual was %d\n",
+                    i, lev);
+            return 2;
+        }
+
+        lev = psTraceGetLevel(".");
+        if (lev != 3) {
+            fprintf(stderr,"ERROR: (.) expected trace level was %d, actual was %d\n",
+                    i, 3);
+            return 3;
+        }
+    }
+
+
+    (void)psTraceSetLevel(".NODE00.NODE01", 4);
+    for (i=0;i<10;i++) {
+        (void)psTraceSetLevel(".NODE00.NODE01", i);
+        lev = psTraceGetLevel(".NODE00.NODE01");
+        if (lev != i) {
+            fprintf(stderr,"ERROR: (.NODE00.NODE01) expected trace level was %d, actual was %d\n",
+                    i, lev);
+            return 4;
+        }
+    }
+
+    return 0;
+}
+
+static int testTrace01(void)
+{
+    psTraceSetDestination(stderr);
+    (void)psTraceSetLevel(".A.B.C.D.E", 5);
+
+    psTracePrintLevels();
+
+    return 0;
+}
+
+static int testTrace02(void)
+{
+    psTraceReset();
+    psTraceSetDestination(stderr);
+    psTraceSetLevel(".A.B", 2);
+    psTraceSetLevel(".A.B.C.D.E", 5);
+    psTracePrintLevels();
+    psTraceSetLevel(".A.B", 10);
+    psTracePrintLevels();
+
+    if (10 != psTraceGetLevel(".A.B.C")) {
+        fprintf(stderr,"ERROR: .A.B.C did not dynamically inherit a trace level (%d)\n",
+                psTraceGetLevel(".A.B.C"));
+        return 2;
+    }
+
+    if (10 != psTraceGetLevel(".A.B.C.D")) {
+        fprintf(stderr,"ERROR: .A.B.C.D did not dynamically inherit a trace level (%d)\n", psTraceGetLevel(".A.B.C.D"));
+        return 2;
+    }
+
+    if (5 != psTraceGetLevel(".A.B.C.D.E")) {
+        fprintf(stderr,"ERROR: .A.B.C.D.E did dynamically inherit a trace level (%d)\n", psTraceGetLevel(".A.B.C.D.E"));
+        return 2;
+    }
+
+    return 0;
+}
+
+static int testTrace03(void)
+{
+    int i = 0;
+    int lev = 0;
+
+    psTraceSetDestination(stderr);
+
+    for (i=0;i<10;i++) {
+        (void)psTraceSetLevel(".", i);
+        psTraceReset();
+
+        lev = psTraceGetLevel(".");
+        if (lev != PS_UNKNOWN_TRACE_LEVEL) {
+            fprintf(stderr,"ERROR: expected trace level was %d, actual was %d\n",
+                    PS_UNKNOWN_TRACE_LEVEL, lev);
+            return 1;
+        }
+    }
+    (void)psTraceSetLevel(".", 5);
+    (void)psTraceSetLevel(".a", 4);
+    (void)psTraceSetLevel(".a.b", 3);
+    (void)psTraceSetLevel(".a.b.c", 2);
+    if ((5 != psTraceGetLevel(".")) ||
+            (4 != psTraceGetLevel(".a")) ||
+            (3 != psTraceGetLevel(".a.b")) ||
+            (2 != psTraceGetLevel(".a.b.c"))) {
+        fprintf(stderr,"ERROR: trace successFlag = false;levels were not settable?\n");
+        return 2;
+    }
+
+    psTraceReset();
+    if ((PS_UNKNOWN_TRACE_LEVEL != psTraceGetLevel(".")) ||
+            (PS_UNKNOWN_TRACE_LEVEL != psTraceGetLevel(".a")) ||
+            (PS_UNKNOWN_TRACE_LEVEL != psTraceGetLevel(".a.b")) ||
+            (PS_UNKNOWN_TRACE_LEVEL != psTraceGetLevel(".a.b.c"))) {
+        fprintf(stderr,"ERROR: trace levels were not reset properly\n");
+        return 3;
+    }
+
+    return 0;
+}
+
+
+static int testTrace04(void)
+{
+    FILE *fp;
+    int nb = 0;
+
+    fp = fopen("tst_psTrace02_OUT", "w");
+    for (nb = 0 ; nb<4;nb++) {
+        if (nb == 0)
+            psTraceSetDestination(stdout);
+        if (nb == 1)
+            psTraceSetDestination(stderr);
+        if (nb == 2)
+            psTraceSetDestination(NULL);
+        if (nb == 3)
+            psTraceSetDestination(fp);
+
+        (void)psTraceSetLevel(".", 4);
+        psTrace(".", 5, "(0) This message should not be displayed (%x)\n",
+                0xbeefface);
+        (void)psTraceSetLevel(".", 7);
+        psTrace(".", 5, "(0) This message should be displayed (%x)\n",
+                0xbeefface);
+
+        (void)psTraceSetLevel(".a", 4);
+        psTrace(".a", 5, "(1) This message should not be displayed (%x)\n",
+                0xbeefface);
+        (void)psTraceSetLevel(".a", 7);
+        psTrace(".a", 5, "(1) This message should be displayed (%x)\n",
+                0xbeefface);
+
+
+        (void)psTraceSetLevel(".a.b", 4);
+        psTrace(".a.b", 5, "(2) This message should not be displayed (%x)\n",
+                0xbeefface);
+        (void)psTraceSetLevel(".a.b", 7);
+        psTrace(".a.b", 5, "(2) This message should be displayed (%x)\n",
+                0xbeefface);
+
+    }
+
+    fclose(fp);
+
+    return(0);
+}
+
+static int testTrace05(void)
+{
+    psTraceSetDestination(stderr);
+
+    (void)psTraceSetLevel(".", 9);
+
+    (void)psTraceSetLevel(".a", 8);
+    (void)psTraceSetLevel(".b", 7);
+    (void)psTraceSetLevel(".c", 5);
+
+    (void)psTraceSetLevel(".a.a", 4);
+    (void)psTraceSetLevel(".a.b", 3);
+
+    (void)psTraceSetLevel(".b.a", 2);
+    (void)psTraceSetLevel(".b.b", 1);
+
+    (void)psTraceSetLevel(".c.a", 0);
+    (void)psTraceSetLevel(".c.b", 3);
+    (void)psTraceSetLevel(".c.c", 5);
+
+    psTracePrintLevels();
+
+    return 0;
+
+}
+
+static int testTrace05a(void)
+{
+    (void)psTraceSetLevel(".", 9);
+
+    (void)psTraceSetLevel("a", 8);
+    (void)psTraceSetLevel("b", 7);
+    (void)psTraceSetLevel("c", 5);
+
+    (void)psTraceSetLevel("a.a", 4);
+    (void)psTraceSetLevel("a.b", 3);
+
+    (void)psTraceSetLevel("b.a", 2);
+    (void)psTraceSetLevel("b.b", 1);
+
+    (void)psTraceSetLevel("c.a", 0);
+    (void)psTraceSetLevel("c.b", 3);
+    (void)psTraceSetLevel("c.c", 5);
+
+    psTracePrintLevels();
+
+    return 0;
+
+}
+
+static int testTrace06(void)
+{
+    psTraceSetDestination(stderr);
+
+    (void)psTraceSetLevel(".", 9);
+
+    (void)psTraceSetLevel(".a", 8);
+    (void)psTraceSetLevel(".b", 7);
+    (void)psTraceSetLevel(".c", 5);
+
+    (void)psTraceSetLevel(".a.a", 4);
+    (void)psTraceSetLevel(".a.b", 3);
+
+    (void)psTraceSetLevel(".b.a", 2);
+    (void)psTraceSetLevel(".b.b", 1);
+
+    (void)psTraceSetLevel(".c.a", 0);
+    (void)psTraceSetLevel(".c.b", 3);
+    (void)psTraceSetLevel(".c.c", 5);
+
+    psTraceReset();
+
+    if ((psTraceGetLevel(".")!=PS_UNKNOWN_TRACE_LEVEL) ||
+            (psTraceGetLevel(".a")!=PS_UNKNOWN_TRACE_LEVEL) ||
+            (psTraceGetLevel(".b")!=PS_UNKNOWN_TRACE_LEVEL) ||
+            (psTraceGetLevel(".c")!=PS_UNKNOWN_TRACE_LEVEL) ||
+            (psTraceGetLevel(".a.a")!=PS_UNKNOWN_TRACE_LEVEL) ||
+            (psTraceGetLevel(".a.b")!=PS_UNKNOWN_TRACE_LEVEL) ||
+            (psTraceGetLevel(".b.a")!=PS_UNKNOWN_TRACE_LEVEL) ||
+            (psTraceGetLevel(".b.b")!=PS_UNKNOWN_TRACE_LEVEL) ||
+            (psTraceGetLevel(".c.a")!=PS_UNKNOWN_TRACE_LEVEL) ||
+            (psTraceGetLevel(".c.b")!=PS_UNKNOWN_TRACE_LEVEL) ||
+            (psTraceGetLevel(".c.c")!=PS_UNKNOWN_TRACE_LEVEL)) {
+        return 1;
+    }
+
+    return 0;
+}
+
+// Ensure that the leading dot in the component names are optional.
+static int testTrace08(void)
+{
+    psTraceReset();
+    (void)psTraceSetLevel(".", 9);
+
+    (void)psTraceSetLevel(".a", 8);
+    (void)psTraceSetLevel(".b", 7);
+    (void)psTraceSetLevel(".c", 5);
+
+    (void)psTraceSetLevel(".a.a", 4);
+    (void)psTraceSetLevel(".a.b", 3);
+
+    (void)psTraceSetLevel(".b.a", 2);
+    (void)psTraceSetLevel(".b.b", 1);
+
+    (void)psTraceSetLevel(".c.a", 0);
+    (void)psTraceSetLevel(".c.b", 3);
+    (void)psTraceSetLevel(".c.c", 5);
+
+    psTracePrintLevels();
+
+    if ((psTraceGetLevel(".")!=9) ||
+            (psTraceGetLevel("a")!=8) ||
+            (psTraceGetLevel("b")!=7) ||
+            (psTraceGetLevel("c")!=5) ||
+            (psTraceGetLevel("a.a")!=4) ||
+            (psTraceGetLevel("a.b")!=3) ||
+            (psTraceGetLevel("b.a")!=2) ||
+            (psTraceGetLevel("b.b")!=1) ||
+            (psTraceGetLevel("c.a")!=0) ||
+            (psTraceGetLevel("c.b")!=3) ||
+            (psTraceGetLevel("c.c")!=5)) {
+        printf("psTraceGetLevel(.) is %d\n", psTraceGetLevel("."));
+        printf("psTraceGetLevel(a) is %d\n", psTraceGetLevel("a"));
+        printf("psTraceGetLevel(b) is %d\n", psTraceGetLevel("b"));
+        printf("psTraceGetLevel(c) is %d\n", psTraceGetLevel("c"));
+        printf("psTraceGetLevel(a.a) is %d\n", psTraceGetLevel("a.a"));
+        printf("psTraceGetLevel(a.b) is %d\n", psTraceGetLevel("a.b"));
+        printf("psTraceGetLevel(b.a) is %d\n", psTraceGetLevel("b.a"));
+        printf("psTraceGetLevel(b.b) is %d\n", psTraceGetLevel("b.b"));
+        printf("psTraceGetLevel(c.a) is %d\n", psTraceGetLevel("c.a"));
+        printf("psTraceGetLevel(c.b) is %d\n", psTraceGetLevel("c.b"));
+        printf("psTraceGetLevel(c.c) is %d\n", psTraceGetLevel("c.c"));
+
+        return 1;
+    }
+
+    return 0;
+}
Index: /branches/rel3/psLib/test/sysUtils/verified/tst_psAbort.stderr
===================================================================
--- /branches/rel3/psLib/test/sysUtils/verified/tst_psAbort.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/verified/tst_psAbort.stderr	(revision 2163)
@@ -0,0 +1,32 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psAbort.c                                              *
+*            TestPoint: psAbort{Multiple type values in abort message}             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|A|testAbort00
+    ALL TYPES intval = 1 longval = 2 floatval = 3.010000 charval = E strval = E R R O R
+
+---> TESTPOINT PASSED (psAbort{Multiple type values in abort message} | tst_psAbort.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psAbort.c                                              *
+*            TestPoint: psAbort{String values in abort message}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|A|__LINE__
+    NO_VALUES
+
+---> TESTPOINT PASSED (psAbort{String values in abort message} | tst_psAbort.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psAbort.c                                              *
+*            TestPoint: psAbort{Empty strings in abort message}                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|A|
+
+---> TESTPOINT PASSED (psAbort{Empty strings in abort message} | tst_psAbort.c)
+
Index: /branches/rel3/psLib/test/sysUtils/verified/tst_psError.stderr
===================================================================
--- /branches/rel3/psLib/test/sysUtils/verified/tst_psError.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/verified/tst_psError.stderr	(revision 2163)
@@ -0,0 +1,116 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psError.c                                              *
+*            TestPoint: psError{psError()}                                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|testError00
+    ALL TYPES intval = 1 longval = 2 floatval = 3.010000 charval = E strval = E R R O R
+<DATE><TIME>|<HOST>|E|__LINE__
+    NO VALUES
+<DATE><TIME>|<HOST>|E|
+
+---> TESTPOINT PASSED (psError{psError()} | tst_psError.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psError.c                                              *
+*            TestPoint: psError{psErrorMsg(),psErrorStackPrint()}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|test1A
+    Error code = 262
+ERROR STACK PRINT Test1A -> test1A: parameter is out-of-range
+     Error code = 262
+<DATE><TIME>|<HOST>|E|
+    Error code = 263
+ERROR STACK PRINT Test1B -> : parameter is of unsupported type
+     Error code = 263
+<DATE><TIME>|<HOST>|E|
+    Error code = 264
+ERROR STACK PRINT Test1C -> : parameter is null
+     Error code = 264
+<DATE><TIME>|<HOST>|E|test1D
+    Error code = -1
+ERROR STACK PRINT Test1D -> test1D: (null)
+     Error code = -1
+<DATE><TIME>|<HOST>|E|test1E
+    Error code = 262
+ERROR STACK PRINT Test1E -> test1D: (null)
+     Error code = -1
+ -> test1E: parameter is out-of-range
+     Error code = 262
+<DATE><TIME>|<HOST>|E|test1F
+    Errno code = 9
+ERROR STACK PRINT Test1F -> test1F: Bad file descriptor
+     Errno code = 9
+
+---> TESTPOINT PASSED (psError{psErrorMsg(),psErrorStackPrint()} | tst_psError.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psError.c                                              *
+*            TestPoint: psError{psErrorStackPrintV()}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|test2A
+    Error code = 262
+ERROR STACK PRINT Test2A -> test2A: parameter is out-of-range
+     Error code = 262
+
+---> TESTPOINT PASSED (psError{psErrorStackPrintV()} | tst_psError.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psError.c                                              *
+*            TestPoint: psError{psErrorGet(),psErrorLast()}                        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|test3A
+    Error code = 262
+<DATE><TIME>|<HOST>|E|test3A
+    Error code = 263
+<DATE><TIME>|<HOST>|E|test3A
+    Error code = 264
+
+---> TESTPOINT PASSED (psError{psErrorGet(),psErrorLast()} | tst_psError.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psError.c                                              *
+*            TestPoint: psError{psErrorClear()}                                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|test4A
+    Error code = 262
+<DATE><TIME>|<HOST>|E|test4A
+    Error code = 263
+<DATE><TIME>|<HOST>|E|test4A
+    Error code = 264
+
+---> TESTPOINT PASSED (psError{psErrorClear()} | tst_psError.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psError.c                                              *
+*            TestPoint: psError{psErrorCodeString()}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|tst_psError05
+    parameter is out-of-range
+
+---> TESTPOINT PASSED (psError{psErrorCodeString()} | tst_psError.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psError.c                                              *
+*            TestPoint: psError{psErrorRegister()}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|testErrorRegister
+    Following should be an error.
+<DATE><TIME>|<HOST>|E|psLib.sysUtils.psErrorRegister
+    Specified psErrorDescription pointer can not be NULL.
+
+---> TESTPOINT PASSED (psError{psErrorRegister()} | tst_psError.c)
+
Index: /branches/rel3/psLib/test/sysUtils/verified/tst_psHash00.stdout
===================================================================
--- /branches/rel3/psLib/test/sysUtils/verified/tst_psHash00.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/verified/tst_psHash00.stdout	(revision 2163)
@@ -0,0 +1,9 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash00.c                                             *
+*            TestPoint: psHash functions{psHashAlloc()}                            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHash functions{psHashAlloc()} | tst_psHash00.c)
+
Index: /branches/rel3/psLib/test/sysUtils/verified/tst_psHash01.stdout
===================================================================
--- /branches/rel3/psLib/test/sysUtils/verified/tst_psHash01.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/verified/tst_psHash01.stdout	(revision 2163)
@@ -0,0 +1,9 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash01.c                                             *
+*            TestPoint: psHash functions{psHashFree()}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHash functions{psHashFree()} | tst_psHash01.c)
+
Index: /branches/rel3/psLib/test/sysUtils/verified/tst_psHash03.stdout
===================================================================
--- /branches/rel3/psLib/test/sysUtils/verified/tst_psHash03.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/verified/tst_psHash03.stdout	(revision 2163)
@@ -0,0 +1,9 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash03.c                                             *
+*            TestPoint: psHash functions{psHashRemove()}                           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psHash functions{psHashRemove()} | tst_psHash03.c)
+
Index: /branches/rel3/psLib/test/sysUtils/verified/tst_psHash04.stdout
===================================================================
--- /branches/rel3/psLib/test/sysUtils/verified/tst_psHash04.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/verified/tst_psHash04.stdout	(revision 2163)
@@ -0,0 +1,13 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psHash04.c                                             *
+*            TestPoint: psHash functions{psHashKeyList()}                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Linked List Entries: ENTRY03
+Linked List Entries: ENTRY02
+Linked List Entries: ENTRY01
+Linked List Entries: ENTRY00
+
+---> TESTPOINT PASSED (psHash functions{psHashKeyList()} | tst_psHash04.c)
+
Index: /branches/rel3/psLib/test/sysUtils/verified/tst_psLogMsg.stderr
===================================================================
--- /branches/rel3/psLib/test/sysUtils/verified/tst_psLogMsg.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/verified/tst_psLogMsg.stderr	(revision 2163)
@@ -0,0 +1,168 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLogMsg.c                                             *
+*            TestPoint: psLogMsg{default log levels, printf-style strings}         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|A|testLogMsg00
+    Hello World!  My level is 0 0.000000 beep beep
+<DATE><TIME>|<HOST>|E|testLogMsg00
+    Hello World!  My level is 1 1.000000 beep beep
+<DATE><TIME>|<HOST>|W|testLogMsg00
+    Hello World!  My level is 2 2.000000 beep beep
+<DATE><TIME>|<HOST>|I|testLogMsg00
+    Hello World!  My level is 3 3.000000 beep beep
+
+---> TESTPOINT PASSED (psLogMsg{default log levels, printf-style strings} | tst_psLogMsg.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLogMsg.c                                             *
+*            TestPoint: psLogMsg{default log levels, psVLogMsg()}                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|A|testLogMsg01
+    Hello World!  My level is 0 0.000000 beep beep
+<DATE><TIME>|<HOST>|E|testLogMsg01
+    Hello World!  My level is 1 1.000000 beep beep
+<DATE><TIME>|<HOST>|W|testLogMsg01
+    Hello World!  My level is 2 2.000000 beep beep
+<DATE><TIME>|<HOST>|I|testLogMsg01
+    Hello World!  My level is 3 3.000000 beep beep
+
+---> TESTPOINT PASSED (psLogMsg{default log levels, psVLogMsg()} | tst_psLogMsg.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLogMsg.c                                             *
+*            TestPoint: psLogMsg{psLogSetLevel()}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|A|testLogMsg02
+    Hello World!  My level is 0
+<DATE><TIME>|<HOST>|E|testLogMsg02
+    Hello World!  My level is 1
+<DATE><TIME>|<HOST>|W|testLogMsg02
+    Hello World!  My level is 2
+<DATE><TIME>|<HOST>|I|testLogMsg02
+    Hello World!  My level is 3
+<DATE><TIME>|<HOST>|4|testLogMsg02
+    Hello World!  My level is 4
+<DATE><TIME>|<HOST>|5|testLogMsg02
+    Hello World!  My level is 5
+<DATE><TIME>|<HOST>|6|testLogMsg02
+    Hello World!  My level is 6
+<DATE><TIME>|<HOST>|7|testLogMsg02
+    Hello World!  My level is 7
+<DATE><TIME>|<HOST>|8|testLogMsg02
+    Hello World!  My level is 8
+<DATE><TIME>|<HOST>|9|testLogMsg02
+    Hello World!  My level is 9
+<DATE><TIME>|<HOST>|4|testLogMsg02
+    This should  be displayed (level 4)
+
+---> TESTPOINT PASSED (psLogMsg{psLogSetLevel()} | tst_psLogMsg.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLogMsg.c                                             *
+*            TestPoint: psLogMsg{psLogSetFormat()}                                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+------------- psLogSetFormat() -------------
+<DATE><TIME>|<HOST>|A|testLogMsg03
+    Hello World!  My level is 0
+<DATE><TIME>|<HOST>|E|testLogMsg03
+    Hello World!  My level is 1
+<DATE><TIME>|<HOST>|W|testLogMsg03
+    Hello World!  My level is 2
+<DATE><TIME>|<HOST>|I|testLogMsg03
+    Hello World!  My level is 3
+------------- psLogSetFormat(NULL) -------------
+------------- psLogSetFormat(T) -------------
+<DATE><TIME>
+
+<DATE><TIME>
+
+<DATE><TIME>
+
+<DATE><TIME>
+
+------------- psLogSetFormat(H) -------------
+<HOST>
+<HOST>
+<HOST>
+<HOST>
+------------- psLogSetFormat(L) -------------
+A
+
+E
+
+W
+
+I
+
+------------- psLogSetFormat(N) -------------
+testLogMsg03
+
+testLogMsg03
+
+testLogMsg03
+
+testLogMsg03
+
+------------- psLogSetFormat(M) -------------
+    Hello World!  My level is 0
+    Hello World!  My level is 1
+    Hello World!  My level is 2
+    Hello World!  My level is 3
+------------- psLogSetFormat(THLNM) -------------
+<DATE><TIME>|<HOST>|A|testLogMsg03
+    Hello World!  My level is 0
+<DATE><TIME>|<HOST>|E|testLogMsg03
+    Hello World!  My level is 1
+<DATE><TIME>|<HOST>|W|testLogMsg03
+    Hello World!  My level is 2
+<DATE><TIME>|<HOST>|I|testLogMsg03
+    Hello World!  My level is 3
+
+---> TESTPOINT PASSED (psLogMsg{psLogSetFormat()} | tst_psLogMsg.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLogMsg.c                                             *
+*            TestPoint: psLogMsg{Output Format}                                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|A|Under 15 chars
+    Hello World!
+<DATE><TIME>|<HOST>|A|This string is more than 15 chars
+    Hello World!
+<DATE><TIME>|<HOST>|A|testLogMsg04
+    Line #1
+<DATE><TIME>|<HOST>|A|testLogMsg04
+    Line #2
+<DATE><TIME>|<HOST>|A|testLogMsg04
+    Line #3
+<DATE><TIME>|<HOST>|A|testLogMsg04
+    Line #4
+
+---> TESTPOINT PASSED (psLogMsg{Output Format} | tst_psLogMsg.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psLogMsg.c                                             *
+*            TestPoint: psLogMsg{psLogSetDestination()}                            *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|A|testLogMsg05
+    Hello World!  My level is 0
+<DATE><TIME>|<HOST>|E|testLogMsg05
+    Hello World!  My level is 1
+<DATE><TIME>|<HOST>|W|testLogMsg05
+    Hello World!  My level is 2
+<DATE><TIME>|<HOST>|I|testLogMsg05
+    Hello World!  My level is 3
+
+---> TESTPOINT PASSED (psLogMsg{psLogSetDestination()} | tst_psLogMsg.c)
+
Index: /branches/rel3/psLib/test/sysUtils/verified/tst_psLogMsg.stdout
===================================================================
--- /branches/rel3/psLib/test/sysUtils/verified/tst_psLogMsg.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/verified/tst_psLogMsg.stdout	(revision 2163)
@@ -0,0 +1,22 @@
+--------------- psLogSetDestination(PS_LOG_NONE) ----------------
+------------- psLogSetDestination(PS_LOG_TO_STDERR) -------------
+------------- psLogSetDestination(PS_LOG_TO_STDOUT) -------------
+<DATE><TIME>|<HOST>|A|testLogMsg05
+    Hello World!  My level is 0
+<DATE><TIME>|<HOST>|E|testLogMsg05
+    Hello World!  My level is 1
+<DATE><TIME>|<HOST>|W|testLogMsg05
+    Hello World!  My level is 2
+<DATE><TIME>|<HOST>|I|testLogMsg05
+    Hello World!  My level is 3
+--------------- psLogSetDestination(file:log.txt) ---------------
+--------------------- The Contents of log.txt -------------------
+<DATE><TIME>|<HOST>|A|testLogMsg05
+    Hello World!  My level is 0
+<DATE><TIME>|<HOST>|E|testLogMsg05
+    Hello World!  My level is 1
+<DATE><TIME>|<HOST>|W|testLogMsg05
+    Hello World!  My level is 2
+<DATE><TIME>|<HOST>|I|testLogMsg05
+    Hello World!  My level is 3
+--------------- psLogSetDestination(file:/eva/log.txt) ----------
Index: /branches/rel3/psLib/test/sysUtils/verified/tst_psMemory.stderr
===================================================================
--- /branches/rel3/psLib/test/sysUtils/verified/tst_psMemory.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/verified/tst_psMemory.stderr	(revision 2163)
@@ -0,0 +1,152 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMemory.c                                             *
+*            TestPoint: psMemory{checkBufferPositive}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|TPCheckBufferPositive
+    psAlloc shall allocate memory blocks writeable by caller.
+
+---> TESTPOINT PASSED (psMemory{checkBufferPositive} | tst_psMemory.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMemory.c                                             *
+*            TestPoint: psMemory{outOfMemory}                                      *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|TPOutOfMemory
+    Upon requesting more memory than is available, psalloc shall call the psMemExhaustedCallback.
+<DATE><TIME>|<HOST>|I|TPOutOfMemoryExhaustedCallback
+    Custom MemExhaustedCallback was invoked.
+<DATE><TIME>|<HOST>|A|p_psAlloc
+    Failed to allocate <N> bytes at tst_psMemory.c:<LINENO>
+
+---> TESTPOINT PASSED (psMemory{outOfMemory} | tst_psMemory.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMemory.c                                             *
+*            TestPoint: psMemory{reallocOutOfMemory}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|TPReallocOutOfMemory
+    Upon requesting more memory than is available, psRealloc shall call the psMemExhaustedCallback.
+<DATE><TIME>|<HOST>|I|TPOutOfMemoryExhaustedCallback
+    Custom MemExhaustedCallback was invoked.
+<DATE><TIME>|<HOST>|A|p_psRealloc
+    Failed to reallocate <N> bytes at tst_psMemory.c:<LINENO>
+
+---> TESTPOINT PASSED (psMemory{reallocOutOfMemory} | tst_psMemory.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMemory.c                                             *
+*            TestPoint: psMemory{psRealloc}                                        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|TPrealloc
+    psRealloc shall increase/decrease memory buffer while preserving contents
+<DATE><TIME>|<HOST>|I|TPrealloc
+    Expanding memory buffer.
+<DATE><TIME>|<HOST>|I|TPrealloc
+    Shrinking memory buffer.
+
+---> TESTPOINT PASSED (psMemory{psRealloc} | tst_psMemory.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMemory.c                                             *
+*            TestPoint: psMemory{allocCallback}                                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|TPallocCallback
+    call to psAlloc/psRealloc shall generate a callback if specified memory ID is allocated.
+<DATE><TIME>|<HOST>|I|memAllocateCallback
+    block 2 was (re)allocated
+<DATE><TIME>|<HOST>|I|memAllocateCallback
+    block 3 was (re)allocated
+<DATE><TIME>|<HOST>|I|memFreeCallback
+    block 2 was freed
+<DATE><TIME>|<HOST>|I|memFreeCallback
+    block 3 was freed
+<DATE><TIME>|<HOST>|I|memAllocateCallback
+    block 4 was (re)allocated
+<DATE><TIME>|<HOST>|I|memAllocateCallback
+    block 4 was (re)allocated
+<DATE><TIME>|<HOST>|I|memFreeCallback
+    block 4 was freed
+
+---> TESTPOINT PASSED (psMemory{allocCallback} | tst_psMemory.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMemory.c                                             *
+*            TestPoint: psMemory{checkLeaks}                                       *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|TPcheckLeaks
+    psMemCheckLeaks shall return the number of blocks above an ID that are still allocated
+<DATE><TIME>|<HOST>|I|TPcheckLeaks
+    following psMemCheckLeaks call should produce one instance.
+                   file:line ID
+         tst_psMemory.c:<LINENO>  1
+<DATE><TIME>|<HOST>|I|TPcheckLeaks
+    Testing psMemCheckLeaks again with a different leak location
+<DATE><TIME>|<HOST>|I|TPcheckLeaks
+    following psMemCheckLeaks call should produce one error.
+                   file:line ID
+         tst_psMemory.c:<LINENO>  11
+<DATE><TIME>|<HOST>|I|TPcheckLeaks
+    Testing psMemCheckLeaks again with multiple leak locations.
+<DATE><TIME>|<HOST>|I|TPcheckLeaks
+    following psMemCheckLeaks call should produce two errors.
+                   file:line ID
+         tst_psMemory.c:<LINENO>  16
+         tst_psMemory.c:<LINENO>  14
+
+---> TESTPOINT PASSED (psMemory{checkLeaks} | tst_psMemory.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMemory.c                                             *
+*            TestPoint: psMemory{psMemCorruption}                                  *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|TPmemCorruption
+    psMemCheckCorruption shall detect memory corruptions
+<DATE><TIME>|<HOST>|I|TPmemCorruption
+    psMemCheckCorruption should output an error message and memProblemCallback callback should be called.
+<DATE><TIME>|<HOST>|E|psLib.sysUtils.checkMemBlock
+    Memory block 1 is corrupted; buffer underflow detected.
+<DATE><TIME>|<HOST>|I|memProblemCallback
+    memory callback called for id 1 (psMemCheckCorruption:<LINENO>).
+
+---> TESTPOINT PASSED (psMemory{psMemCorruption} | tst_psMemory.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMemory.c                                             *
+*            TestPoint: psMemory{freeReferencedMemory}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|TPFreeReferencedMemory
+    memory reference count shall be incrementable/decrementable
+<DATE><TIME>|<HOST>|I|TPFreeReferencedMemory
+    psFree shall be just decrement a multiple refererenced pointer.
+
+---> TESTPOINT PASSED (psMemory{freeReferencedMemory} | tst_psMemory.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psMemory.c                                             *
+*            TestPoint: psMemory{multipleFree}                                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|I|TPmultipleFree
+    Next should be an error about multiple freeing.
+<DATE><TIME>|<HOST>|E|psLib.sysUtils.psFree
+    Block 1, allocated at tst_psMemory.c:<LINENO>, freed multiple times at tst_psMemory.c:<LINENO>.
+
+---> TESTPOINT PASSED (psMemory{multipleFree} | tst_psMemory.c)
+
Index: /branches/rel3/psLib/test/sysUtils/verified/tst_psStringCopy.stderr
===================================================================
--- /branches/rel3/psLib/test/sysUtils/verified/tst_psStringCopy.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/verified/tst_psStringCopy.stderr	(revision 2163)
@@ -0,0 +1,65 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStringCopy.c                                         *
+*            TestPoint: psString{Verify string copy}                               *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psString{Verify string copy} | tst_psStringCopy.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStringCopy.c                                         *
+*            TestPoint: psString{Verify empty string copy}                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psString{Verify empty string copy} | tst_psStringCopy.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStringCopy.c                                         *
+*            TestPoint: psString{Verify string copy with length}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psString{Verify string copy with length} | tst_psStringCopy.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStringCopy.c                                         *
+*            TestPoint: psString{Verify empty string copy with length}             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psString{Verify empty string copy with length} | tst_psStringCopy.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStringCopy.c                                         *
+*            TestPoint: psString{Copy string to larger string}                     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psString{Copy string to larger string} | tst_psStringCopy.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStringCopy.c                                         *
+*            TestPoint: psString{Copy string with negative size}                   *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psLib.sysUtils.psStringNCopy
+    Can not copy a negative number of characters (-5).
+
+---> TESTPOINT PASSED (psString{Copy string with negative size} | tst_psStringCopy.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psStringCopy.c                                         *
+*            TestPoint: psString{Verify creation of string literal}                *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psString{Verify creation of string literal} | tst_psStringCopy.c)
+
Index: /branches/rel3/psLib/test/sysUtils/verified/tst_psTrace.stderr
===================================================================
--- /branches/rel3/psLib/test/sysUtils/verified/tst_psTrace.stderr	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/verified/tst_psTrace.stderr	(revision 2163)
@@ -0,0 +1,113 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace.c                                              *
+*            TestPoint: psTrace{psTraceSetLevel() and psTraceGetLevel()}           *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTrace{psTraceSetLevel() and psTraceGetLevel()} | tst_psTrace.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace.c                                              *
+*            TestPoint: psTrace{psTraceSetLevel(): set multiple components in one call} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+.                    -1
+ A                   -1
+  B                  -1
+   C                 -1
+    D                -1
+     E               5
+
+---> TESTPOINT PASSED (psTrace{psTraceSetLevel(): set multiple components in one call} | tst_psTrace.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace.c                                              *
+*            TestPoint: psTrace{psTraceSetLevel(): test static inheritance}        *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+.                    -1
+ A                   -1
+  B                  2
+   C                 2
+    D                2
+     E               5
+.                    -1
+ A                   -1
+  B                  10
+   C                 10
+    D                10
+     E               5
+
+---> TESTPOINT PASSED (psTrace{psTraceSetLevel(): test static inheritance} | tst_psTrace.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace.c                                              *
+*            TestPoint: psTrace{psTraceReset()}                                    *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTrace{psTraceReset()} | tst_psTrace.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace.c                                              *
+*            TestPoint: psTrace{psTrace()}                                         *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+     (0) This message should be displayed (beefface)
+     (1) This message should be displayed (beefface)
+     (2) This message should be displayed (beefface)
+
+---> TESTPOINT PASSED (psTrace{psTrace()} | tst_psTrace.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace.c                                              *
+*            TestPoint: psTrace{psTracePrintLevels()}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+.                    9
+ a                   8
+  a                  4
+  b                  3
+ b                   7
+  a                  2
+  b                  1
+ c                   5
+  a                  0
+  b                  3
+  c                  5
+
+---> TESTPOINT PASSED (psTrace{psTracePrintLevels()} | tst_psTrace.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace.c                                              *
+*            TestPoint: psTrace{optional leading dot and psTracePrintLevels()}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTrace{optional leading dot and psTracePrintLevels()} | tst_psTrace.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace.c                                              *
+*            TestPoint: psTrace{Testing psTraceReset}                              *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTrace{Testing psTraceReset} | tst_psTrace.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_psTrace.c                                              *
+*            TestPoint: psTrace{Testing }                                          *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (psTrace{Testing } | tst_psTrace.c)
+
Index: /branches/rel3/psLib/test/sysUtils/verified/tst_psTrace.stdout
===================================================================
--- /branches/rel3/psLib/test/sysUtils/verified/tst_psTrace.stdout	(revision 2163)
+++ /branches/rel3/psLib/test/sysUtils/verified/tst_psTrace.stdout	(revision 2163)
@@ -0,0 +1,28 @@
+     (0) This message should be displayed (beefface)
+     (1) This message should be displayed (beefface)
+     (2) This message should be displayed (beefface)
+     (0) This message should be displayed (beefface)
+     (1) This message should be displayed (beefface)
+     (2) This message should be displayed (beefface)
+.                    9
+ a                   8
+  a                  4
+  b                  3
+ b                   7
+  a                  2
+  b                  1
+ c                   5
+  a                  0
+  b                  3
+  c                  5
+.                    9
+ a                   8
+  a                  4
+  b                  3
+ b                   7
+  a                  2
+  b                  1
+ c                   5
+  a                  0
+  b                  3
+  c                  5
Index: /branches/rel3/psLib/test/tst_template.c
===================================================================
--- /branches/rel3/psLib/test/tst_template.c	(revision 2163)
+++ /branches/rel3/psLib/test/tst_template.c	(revision 2163)
@@ -0,0 +1,92 @@
+/** @file  tst_psImageManip.c
+*
+*  @brief Contains the tests for psImageManip.[ch]
+*
+*
+*  @author Robert DeSonia, MHPCC
+*
+*  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2004-08-02 18:30:10 $
+*
+*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+*/
+
+#include "psTest.h"
+#include "pslib.h"
+
+static int test1( void );
+static int test2( void );
+static int test3( void );
+
+// test descrription consists of:
+//    * test function
+//
+//    * testpoint number (item number in gforge testpoint log)
+//
+//    * name of the testpoint
+//
+//    * expected return value (negative numbers are signal types, e.g.,
+//      -6 for aborts).  Usually either -6 (psAbort called) or 0.
+//
+//    * boolean to signify if the test function is already in list, i.e., if
+//      the test function covers multiple testpoints.  If true, the line is
+//      ignored by runTestSuite if the user didn't explicitly specify the
+//      testpoint with the -n or -t option, as to not run a test function
+//      multiple times.
+//
+testDescription tests[] = {
+                              {
+                                  test1, 1111, "psFunctionBar", 0, false
+                              },
+                              {
+                                  test2, 1113, "psFunctionFoo", 0, false
+                              },
+                              {
+                                  test3, 1114, "psFunctionFunk", 0, false
+                              },
+                              
+                              // testpoint #1112 handled by same test function as #1111
+                              {
+                                  test1, 1112, "psFunctionBang", 0, true
+                              },
+                              
+                              // A null terminates the testDescription list
+                              {
+                                  NULL
+                              }
+                          };
+                          
+int main( int argc, char* argv[] )
+{
+    psLogSetLevel( PS_LOG_INFO );
+    
+    return ( ! runTestSuite( stderr, "psImage", tests, argc, argv ) );
+}
+
+int test1( void )
+{
+    // no need to check for memory leaks, as the runTestSuite does that for you.
+    
+    // here is where one implements the tests for generally a single testpoint.
+    
+    return 0;  // the value that indicates success is part of the testDescription
+}
+
+int test2( void )
+{
+    // no need to check for memory leaks, as the runTestSuite does that for you.
+    
+    // here is where one implements the tests for generally a single testpoint.
+    
+    return 0;  // the value that indicates success is part of the testDescription
+}
+
+int test3( void )
+{
+    // no need to check for memory leaks, as the runTestSuite does that for you.
+    
+    // here is where one implements the tests for generally a single testpoint.
+    
+    return 0;  // the value that indicates success is part of the testDescription
+}
+
Index: /branches/rel3/psModules/.cvsignore
===================================================================
--- /branches/rel3/psModules/.cvsignore	(revision 2163)
+++ /branches/rel3/psModules/.cvsignore	(revision 2163)
@@ -0,0 +1,5 @@
+autom4te.cache
+Makefile
+config.log
+config.status
+libtool
Index: /branches/rel3/psModules/AUTHORS
===================================================================
--- /branches/rel3/psModules/AUTHORS	(revision 2163)
+++ /branches/rel3/psModules/AUTHORS	(revision 2163)
@@ -0,0 +1,1 @@
+Maui High Performance Computing Center, University of Hawai'i
Index: /branches/rel3/psModules/COPYING
===================================================================
--- /branches/rel3/psModules/COPYING	(revision 2163)
+++ /branches/rel3/psModules/COPYING	(revision 2163)
@@ -0,0 +1,6 @@
+(C) 2004 University of Hawai'i
+
+Permission to copy/distribute to be governed by:
+    Institute for Astronomy
+    2680 Woodlawn Drive
+    Honolulu, HI 96822-1897
Index: /branches/rel3/psModules/ChangeLog
===================================================================
--- /branches/rel3/psModules/ChangeLog	(revision 2163)
+++ /branches/rel3/psModules/ChangeLog	(revision 2163)
@@ -0,0 +1,1 @@
+ 
Index: /branches/rel3/psModules/INSTALL
===================================================================
--- /branches/rel3/psModules/INSTALL	(revision 2163)
+++ /branches/rel3/psModules/INSTALL	(revision 2163)
@@ -0,0 +1,167 @@
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+   The file `configure.in' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes a while.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Type `make install' to install the programs and any data files and
+     documentation.
+
+  4. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  You can give `configure'
+initial values for variables by setting them in the environment.  Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory.  After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on.  Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+     CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+   If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+     Use and save the results of the tests in FILE instead of
+     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
+     debugging `configure'.
+
+`--help'
+     Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--version'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
+
Index: /branches/rel3/psModules/Makefile.am
===================================================================
--- /branches/rel3/psModules/Makefile.am	(revision 2163)
+++ /branches/rel3/psModules/Makefile.am	(revision 2163)
@@ -0,0 +1,3 @@
+AUTOMAKE_OPTIONS = foreign 1.4
+
+SUBDIRS = src test
Index: /branches/rel3/psModules/Makefile.cvs
===================================================================
--- /branches/rel3/psModules/Makefile.cvs	(revision 2163)
+++ /branches/rel3/psModules/Makefile.cvs	(revision 2163)
@@ -0,0 +1,8 @@
+default: all
+
+all:
+	aclocal
+	autoheader
+	automake
+	autoconf
+
Index: /branches/rel3/psModules/Makefile.in
===================================================================
--- /branches/rel3/psModules/Makefile.in	(revision 2163)
+++ /branches/rel3/psModules/Makefile.in	(revision 2163)
@@ -0,0 +1,570 @@
+# Makefile.in generated by automake 1.8.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = .
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \
+	ChangeLog INSTALL NEWS TODO config.guess config.sub depcomp \
+	install-sh ltmain.sh missing mkinstalldirs
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno configure.status.lineno
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/src/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-exec-recursive install-info-recursive \
+	install-recursive installcheck-recursive installdirs-recursive \
+	pdf-recursive ps-recursive uninstall-info-recursive \
+	uninstall-recursive
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  { test ! -d $(distdir) \
+    || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+         && rm -fr $(distdir); }; }
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GSL_CONFIG = @GSL_CONFIG@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+AUTOMAKE_OPTIONS = foreign 1.4
+SUBDIRS = src test
+all: all-recursive
+
+.SUFFIXES:
+am--refresh:
+	@:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \
+	      cd $(srcdir) && $(AUTOMAKE) --foreign  \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign  Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    echo ' $(SHELL) ./config.status'; \
+	    $(SHELL) ./config.status;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool
+uninstall-info-am:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@set fnord $$MAKEFLAGS; amf=$$2; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	   || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+	@set fnord $$MAKEFLAGS; amf=$$2; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	   || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	if (etags --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	else \
+	  include_option=--include; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -f $$subdir/TAGS && \
+	      tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(ETAGS_ARGS)$$tags$$unique" \
+	  || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	     $$tags $$unique
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	$(am__remove_distdir)
+	mkdir $(distdir)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkdir_p) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || mkdir "$(distdir)/$$subdir" \
+	    || exit 1; \
+	    (cd $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="../$(top_distdir)" \
+	        distdir="../$(distdir)/$$subdir" \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+	-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+	|| chmod -R a+r $(distdir)
+dist-gzip: distdir
+	$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+dist-bzip2: distdir
+	$(AMTAR) chof - $(distdir) | bzip2 -9 -c >$(distdir).tar.bz2
+	$(am__remove_distdir)
+
+dist-tarZ: distdir
+	$(AMTAR) chof - $(distdir) | compress -c >$(distdir).tar.Z
+	$(am__remove_distdir)
+
+dist-shar: distdir
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__remove_distdir)
+
+dist dist-all: distdir
+	$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	case '$(DIST_ARCHIVES)' in \
+	*.tar.gz*) \
+	  GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - ;;\
+	*.tar.bz2*) \
+	  bunzip2 -c $(distdir).tar.bz2 | $(AMTAR) xf - ;;\
+	*.tar.Z*) \
+	  uncompress -c $(distdir).tar.Z | $(AMTAR) xf - ;;\
+	*.shar.gz*) \
+	  GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir); chmod a+w $(distdir)
+	mkdir $(distdir)/_build
+	mkdir $(distdir)/_inst
+	chmod a-w $(distdir)
+	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+	  && cd $(distdir)/_build \
+	  && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+	  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+	        distuninstallcheck \
+	  && chmod -R a-w "$$dc_install_base" \
+	  && ({ \
+	       (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+	            distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+	      } || { rm -rf "$$dc_destdir"; exit 1; }) \
+	  && rm -rf "$$dc_destdir" \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist \
+	  && rm -rf $(DIST_ARCHIVES) \
+	  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+	$(am__remove_distdir)
+	@(echo "$(distdir) archives ready for distribution: "; \
+	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+	  sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
+distuninstallcheck:
+	@cd $(distuninstallcheck_dir) \
+	&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+	   || { echo "ERROR: files left after uninstall:" ; \
+	        if test -n "$(DESTDIR)"; then \
+	          echo "  (check DESTDIR support)"; \
+	        fi ; \
+	        $(distuninstallcheck_listfiles) ; \
+	        exit 1; } >&2
+distcleancheck: distclean
+	@if test '$(srcdir)' = . ; then \
+	  echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+	  exit 1 ; \
+	fi
+	@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+	  || { echo "ERROR: files left in build directory after distclean:" ; \
+	       $(distcleancheck_listfiles) ; \
+	       exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool \
+	distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
+	check-am clean clean-generic clean-libtool clean-recursive \
+	ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \
+	dist-shar dist-tarZ dist-zip distcheck distclean \
+	distclean-generic distclean-libtool distclean-recursive \
+	distclean-tags distcleancheck distdir distuninstallcheck dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-exec install-exec-am \
+	install-info install-info-am install-man install-strip \
+	installcheck installcheck-am installdirs installdirs-am \
+	maintainer-clean maintainer-clean-generic \
+	maintainer-clean-recursive mostlyclean mostlyclean-generic \
+	mostlyclean-libtool mostlyclean-recursive pdf pdf-am ps ps-am \
+	tags tags-recursive uninstall uninstall-am uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
Index: /branches/rel3/psModules/NEWS
===================================================================
--- /branches/rel3/psModules/NEWS	(revision 2163)
+++ /branches/rel3/psModules/NEWS	(revision 2163)
@@ -0,0 +1,1 @@
+ 
Index: /branches/rel3/psModules/README
===================================================================
--- /branches/rel3/psModules/README	(revision 2163)
+++ /branches/rel3/psModules/README	(revision 2163)
@@ -0,0 +1,1 @@
+
Index: /branches/rel3/psModules/TODO
===================================================================
--- /branches/rel3/psModules/TODO	(revision 2163)
+++ /branches/rel3/psModules/TODO	(revision 2163)
@@ -0,0 +1,1 @@
+ 
Index: /branches/rel3/psModules/aclocal.m4
===================================================================
--- /branches/rel3/psModules/aclocal.m4	(revision 2163)
+++ /branches/rel3/psModules/aclocal.m4	(revision 2163)
@@ -0,0 +1,6852 @@
+# generated automatically by aclocal 1.8.3 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+# Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+
+# serial 47 AC_PROG_LIBTOOL
+
+
+# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
+# -----------------------------------------------------------
+# If this macro is not defined by Autoconf, define it here.
+m4_ifdef([AC_PROVIDE_IFELSE],
+         [],
+         [m4_define([AC_PROVIDE_IFELSE],
+	         [m4_ifdef([AC_PROVIDE_$1],
+		           [$2], [$3])])])
+
+
+# AC_PROG_LIBTOOL
+# ---------------
+AC_DEFUN([AC_PROG_LIBTOOL],
+[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl
+dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX
+dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX.
+  AC_PROVIDE_IFELSE([AC_PROG_CXX],
+    [AC_LIBTOOL_CXX],
+    [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX
+  ])])
+dnl And a similar setup for Fortran 77 support
+  AC_PROVIDE_IFELSE([AC_PROG_F77],
+    [AC_LIBTOOL_F77],
+    [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77
+])])
+
+dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly.
+dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run
+dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both.
+  AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+    [AC_LIBTOOL_GCJ],
+    [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+      [AC_LIBTOOL_GCJ],
+      [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],
+	[AC_LIBTOOL_GCJ],
+      [ifdef([AC_PROG_GCJ],
+	     [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])
+       ifdef([A][M_PROG_GCJ],
+	     [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])])
+       ifdef([LT_AC_PROG_GCJ],
+	     [define([LT_AC_PROG_GCJ],
+		defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])])
+])])# AC_PROG_LIBTOOL
+
+
+# _AC_PROG_LIBTOOL
+# ----------------
+AC_DEFUN([_AC_PROG_LIBTOOL],
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Prevent multiple expansion
+define([AC_PROG_LIBTOOL], [])
+])# _AC_PROG_LIBTOOL
+
+
+# AC_LIBTOOL_SETUP
+# ----------------
+AC_DEFUN([AC_LIBTOOL_SETUP],
+[AC_PREREQ(2.50)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+
+AC_REQUIRE([AC_PROG_LN_S])dnl
+AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+AC_REQUIRE([AC_OBJEXT])dnl
+AC_REQUIRE([AC_EXEEXT])dnl
+dnl
+
+AC_LIBTOOL_SYS_MAX_CMD_LEN
+AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+AC_LIBTOOL_OBJDIR
+
+AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+_LT_AC_PROG_ECHO_BACKSLASH
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g']
+
+# Same as above, but do not quote variable references.
+[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g']
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+AC_CHECK_TOOL(AR, ar, false)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(STRIP, strip, :)
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$SED" && SED=sed
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+    ;;
+  *)
+    old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    AC_PATH_MAGIC
+  fi
+  ;;
+esac
+
+AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no)
+AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
+enable_win32_dll=yes, enable_win32_dll=no)
+
+AC_ARG_ENABLE([libtool-lock],
+    [AC_HELP_STRING([--disable-libtool-lock],
+	[avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+AC_ARG_WITH([pic],
+    [AC_HELP_STRING([--with-pic],
+	[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [pic_mode="$withval"],
+    [pic_mode=default])
+test -z "$pic_mode" && pic_mode=default
+
+# Use C for the default configuration in the libtool script
+tagname=
+AC_LIBTOOL_LANG_C_CONFIG
+_LT_AC_TAGCONFIG
+])# AC_LIBTOOL_SETUP
+
+
+# _LT_AC_SYS_COMPILER
+# -------------------
+AC_DEFUN([_LT_AC_SYS_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_AC_SYS_COMPILER
+
+
+# _LT_AC_SYS_LIBPATH_AIX
+# ----------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX],
+[AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi],[])
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+])# _LT_AC_SYS_LIBPATH_AIX
+
+
+# _LT_AC_SHELL_INIT(ARG)
+# ----------------------
+AC_DEFUN([_LT_AC_SHELL_INIT],
+[ifdef([AC_DIVERSION_NOTICE],
+	     [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+	 [AC_DIVERT_PUSH(NOTICE)])
+$1
+AC_DIVERT_POP
+])# _LT_AC_SHELL_INIT
+
+
+# _LT_AC_PROG_ECHO_BACKSLASH
+# --------------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH],
+[_LT_AC_SHELL_INIT([
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+  ;;
+esac
+
+echo=${ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X[$]1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+[$]*
+EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+       echo_test_string="`eval $cmd`" &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+    then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+   echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+   test "X$echo_testing_string" = "X$echo_test_string"; then
+  :
+else
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for dir in $PATH /usr/ucb; do
+    IFS="$lt_save_ifs"
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+	 test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running configure again with it.
+      ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+    else
+      # Try using printf.
+      echo='printf %s\n'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+	 echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+	 test "X$echo_testing_string" = "X$echo_test_string"; then
+	# Cool, printf works
+	:
+      elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+	   test "X$echo_testing_string" = 'X\t' &&
+	   echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+	export CONFIG_SHELL
+	SHELL="$CONFIG_SHELL"
+	export SHELL
+	echo="$CONFIG_SHELL [$]0 --fallback-echo"
+      elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+	   test "X$echo_testing_string" = 'X\t' &&
+	   echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	echo="$CONFIG_SHELL [$]0 --fallback-echo"
+      else
+	# maybe with a smaller string...
+	prev=:
+
+	for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+	  if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+	  then
+	    break
+	  fi
+	  prev="$cmd"
+	done
+
+	if test "$prev" != 'sed 50q "[$]0"'; then
+	  echo_test_string=`eval $prev`
+	  export echo_test_string
+	  exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+	else
+	  # Oops.  We lost completely, so just stick with echo.
+	  echo=echo
+	fi
+      fi
+    fi
+  fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+   ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(ECHO)
+])])# _LT_AC_PROG_ECHO_BACKSLASH
+
+
+# _LT_AC_LOCK
+# -----------
+AC_DEFUN([_LT_AC_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+    [AC_HELP_STRING([--disable-libtool-lock],
+	[avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *ELF-32*)
+      HPUX_IA64_MODE="32"
+      ;;
+    *ELF-64*)
+      HPUX_IA64_MODE="64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+   if test "$lt_cv_prog_gnu_ld" = yes; then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -melf32bsmip"
+      ;;
+    *N32*)
+      LD="${LD-ld} -melf32bmipn32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -melf64bmip"
+      ;;
+    esac
+   else
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+   fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_i386"
+          ;;
+        ppc64-*linux*|powerpc64-*linux*)
+          LD="${LD-ld} -m elf32ppclinux"
+          ;;
+        s390x-*linux*)
+          LD="${LD-ld} -m elf_s390"
+          ;;
+        sparc64-*linux*)
+          LD="${LD-ld} -m elf32_sparc"
+          ;;
+      esac
+      ;;
+    *64-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        ppc*-*linux*|powerpc*-*linux*)
+          LD="${LD-ld} -m elf64ppc"
+          ;;
+        s390*-*linux*)
+          LD="${LD-ld} -m elf64_s390"
+          ;;
+        sparc*-*linux*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_PUSH(C)
+     AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_POP])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+  ])
+esac
+
+need_locks="$enable_libtool_lock"
+
+])# _LT_AC_LOCK
+
+
+# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#		[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION],
+[AC_REQUIRE([LT_AC_PROG_SED])
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+  ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$3"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test ! -s conftest.err; then
+       $2=yes
+     fi
+   fi
+   $rm conftest*
+])
+
+if test x"[$]$2" = xyes; then
+    ifelse([$5], , :, [$5])
+else
+    ifelse([$6], , :, [$6])
+fi
+])# AC_LIBTOOL_COMPILER_OPTION
+
+
+# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                          [ACTION-SUCCESS], [ACTION-FAILURE])
+# ------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([AC_LIBTOOL_LINKER_OPTION],
+[AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $3"
+   printf "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&AS_MESSAGE_LOG_FD
+     else
+       $2=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+    ifelse([$4], , :, [$4])
+else
+    ifelse([$5], , :, [$5])
+fi
+])# AC_LIBTOOL_LINKER_OPTION
+
+
+# AC_LIBTOOL_SYS_MAX_CMD_LEN
+# --------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN],
+[# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+  i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+ *)
+    # If test is not a shell built-in, we'll probably end up computing a
+    # maximum length that is only half of the actual maximum length, but
+    # we can't tell.
+    while (test "X"`$CONFIG_SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \
+	       = "XX$teststring") >/dev/null 2>&1 &&
+	    new_result=`expr "X$teststring" : ".*" 2>&1` &&
+	    lt_cv_sys_max_cmd_len=$new_result &&
+	    test $i != 17 # 1/2 MB should be enough
+    do
+      i=`expr $i + 1`
+      teststring=$teststring$teststring
+    done
+    teststring=
+    # Add a significant safety factor because C++ compilers can tack on massive
+    # amounts of additional arguments before passing them to the linker.
+    # It appears as though 1/2 is a usable value.
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    ;;
+  esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+  AC_MSG_RESULT(none)
+fi
+])# AC_LIBTOOL_SYS_MAX_CMD_LEN
+
+
+# _LT_AC_CHECK_DLFCN
+# --------------------
+AC_DEFUN([_LT_AC_CHECK_DLFCN],
+[AC_CHECK_HEADERS(dlfcn.h)dnl
+])# _LT_AC_CHECK_DLFCN
+
+
+# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                           ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ------------------------------------------------------------------
+AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF],
+[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+  [$4]
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}]
+EOF
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_unknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_AC_TRY_DLOPEN_SELF
+
+
+# AC_LIBTOOL_DLOPEN_SELF
+# -------------------
+AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF],
+[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+   ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+   ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ])
+   ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+	  [lt_cv_dlopen="shl_load"],
+      [AC_CHECK_LIB([dld], [shl_load],
+	    [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"],
+	[AC_CHECK_FUNC([dlopen],
+	      [lt_cv_dlopen="dlopen"],
+	  [AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+	    [AC_CHECK_LIB([svld], [dlopen],
+		  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+	      [AC_CHECK_LIB([dld], [dld_link],
+		    [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
+	      ])
+	    ])
+	  ])
+	])
+      ])
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+	  lt_cv_dlopen_self, [dnl
+	  _LT_AC_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      LDFLAGS="$LDFLAGS $link_static_flag"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+    	  lt_cv_dlopen_self_static, [dnl
+	  _LT_AC_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+	    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+])# AC_LIBTOOL_DLOPEN_SELF
+
+
+# AC_LIBTOOL_PROG_CC_C_O([TAGNAME])
+# ---------------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler
+AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O],
+[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+  [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+  [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test ! -s out/conftest.err; then
+       _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+     fi
+   fi
+   chmod u+w .
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+])
+])# AC_LIBTOOL_PROG_CC_C_O
+
+
+# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME])
+# -----------------------------------------
+# Check to see if we can do hard links to lock some files if needed
+AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS],
+[AC_REQUIRE([_LT_AC_LOCK])dnl
+
+hard_links="nottested"
+if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS
+
+
+# AC_LIBTOOL_OBJDIR
+# -----------------
+AC_DEFUN([AC_LIBTOOL_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+])# AC_LIBTOOL_OBJDIR
+
+
+# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME])
+# ----------------------------------------------
+# Check hardcoding attributes.
+AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_AC_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \
+   test -n "$_LT_AC_TAGVAR(runpath_var $1)" || \
+   test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)"="Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then
+    # Linking always hardcodes the temporary library directory.
+    _LT_AC_TAGVAR(hardcode_action, $1)=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    _LT_AC_TAGVAR(hardcode_action, $1)=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  _LT_AC_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH
+
+
+# AC_LIBTOOL_SYS_LIB_STRIP
+# ------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP],
+[striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+   darwin*)
+       if test -n "$STRIP" ; then
+         striplib="$STRIP -x"
+         AC_MSG_RESULT([yes])
+       else
+  AC_MSG_RESULT([no])
+fi
+       ;;
+   *)
+  AC_MSG_RESULT([no])
+    ;;
+  esac
+fi
+])# AC_LIBTOOL_SYS_LIB_STRIP
+
+
+# AC_LIBTOOL_SYS_DYNAMIC_LINKER
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER],
+[AC_MSG_CHECKING([dynamic linker characteristics])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case "$host_cpu" in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # find out which ABI we are using
+  libsuff=
+  case "$host_cpu" in
+  x86_64*|s390x*|powerpc64*)
+    echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+    if AC_TRY_EVAL(ac_compile); then
+      case `/usr/bin/file conftest.$ac_objext` in
+      *64-bit*)
+        libsuff=64
+        sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+        ;;
+      esac
+    fi
+    rm -rf conftest*
+    ;;
+  esac
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`$SED -e 's/[:,\t]/ /g;s/=[^=]*$//;s/=[^= ]* / /g' /etc/ld.so.conf | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=yes
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+])# AC_LIBTOOL_SYS_DYNAMIC_LINKER
+
+
+# _LT_AC_TAGCONFIG
+# ----------------
+AC_DEFUN([_LT_AC_TAGCONFIG],
+[AC_ARG_WITH([tags],
+    [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@],
+        [include additional configurations @<:@automatic@:>@])],
+    [tagnames="$withval"])
+
+if test -f "$ltmain" && test -n "$tagnames"; then
+  if test ! -f "${ofile}"; then
+    AC_MSG_WARN([output file `$ofile' does not exist])
+  fi
+
+  if test -z "$LTCC"; then
+    eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
+    if test -z "$LTCC"; then
+      AC_MSG_WARN([output file `$ofile' does not look like a libtool script])
+    else
+      AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile'])
+    fi
+  fi
+
+  # Extract list of available tagged configurations in $ofile.
+  # Note that this assumes the entire list is on one line.
+  available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'`
+
+  lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+  for tagname in $tagnames; do
+    IFS="$lt_save_ifs"
+    # Check whether tagname contains only valid characters
+    case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in
+    "") ;;
+    *)  AC_MSG_ERROR([invalid tag name: $tagname])
+	;;
+    esac
+
+    if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null
+    then
+      AC_MSG_ERROR([tag name \"$tagname\" already exists])
+    fi
+
+    # Update the list of available tags.
+    if test -n "$tagname"; then
+      echo appending configuration tag \"$tagname\" to $ofile
+
+      case $tagname in
+      CXX)
+	if test -n "$CXX" && test "X$CXX" != "Xno"; then
+	  AC_LIBTOOL_LANG_CXX_CONFIG
+	else
+	  tagname=""
+	fi
+	;;
+
+      F77)
+	if test -n "$F77" && test "X$F77" != "Xno"; then
+	  AC_LIBTOOL_LANG_F77_CONFIG
+	else
+	  tagname=""
+	fi
+	;;
+
+      GCJ)
+	if test -n "$GCJ" && test "X$GCJ" != "Xno"; then
+	  AC_LIBTOOL_LANG_GCJ_CONFIG
+	else
+	  tagname=""
+	fi
+	;;
+
+      RC)
+	AC_LIBTOOL_LANG_RC_CONFIG
+	;;
+
+      *)
+	AC_MSG_ERROR([Unsupported tag name: $tagname])
+	;;
+      esac
+
+      # Append the new tag name to the list of available tags.
+      if test -n "$tagname" ; then
+      available_tags="$available_tags $tagname"
+    fi
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  # Now substitute the updated list of available tags.
+  if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then
+    mv "${ofile}T" "$ofile"
+    chmod +x "$ofile"
+  else
+    rm -f "${ofile}T"
+    AC_MSG_ERROR([unable to update list of available tagged configurations.])
+  fi
+fi
+])# _LT_AC_TAGCONFIG
+
+
+# AC_LIBTOOL_DLOPEN
+# -----------------
+# enable checks for dlopen support
+AC_DEFUN([AC_LIBTOOL_DLOPEN],
+ [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])
+])# AC_LIBTOOL_DLOPEN
+
+
+# AC_LIBTOOL_WIN32_DLL
+# --------------------
+# declare package support for building win32 dll's
+AC_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_BEFORE([$0], [AC_LIBTOOL_SETUP])
+])# AC_LIBTOOL_WIN32_DLL
+
+
+# AC_ENABLE_SHARED([DEFAULT])
+# ---------------------------
+# implement the --enable-shared flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_SHARED],
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([shared],
+    [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+	[build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_shared=]AC_ENABLE_SHARED_DEFAULT)
+])# AC_ENABLE_SHARED
+
+
+# AC_DISABLE_SHARED
+# -----------------
+#- set the default shared flag to --disable-shared
+AC_DEFUN([AC_DISABLE_SHARED],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)
+])# AC_DISABLE_SHARED
+
+
+# AC_ENABLE_STATIC([DEFAULT])
+# ---------------------------
+# implement the --enable-static flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_STATIC],
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([static],
+    [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+	[build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_static=]AC_ENABLE_STATIC_DEFAULT)
+])# AC_ENABLE_STATIC
+
+
+# AC_DISABLE_STATIC
+# -----------------
+# set the default static flag to --disable-static
+AC_DEFUN([AC_DISABLE_STATIC],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)
+])# AC_DISABLE_STATIC
+
+
+# AC_ENABLE_FAST_INSTALL([DEFAULT])
+# ---------------------------------
+# implement the --enable-fast-install flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_FAST_INSTALL],
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([fast-install],
+    [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+    [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT)
+])# AC_ENABLE_FAST_INSTALL
+
+
+# AC_DISABLE_FAST_INSTALL
+# -----------------------
+# set the default to --disable-fast-install
+AC_DEFUN([AC_DISABLE_FAST_INSTALL],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)
+])# AC_DISABLE_FAST_INSTALL
+
+
+# AC_LIBTOOL_PICMODE([MODE])
+# --------------------------
+# implement the --with-pic flag
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
+AC_DEFUN([AC_LIBTOOL_PICMODE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+pic_mode=ifelse($#,1,$1,default)
+])# AC_LIBTOOL_PICMODE
+
+
+# AC_PROG_EGREP
+# -------------
+# This is predefined starting with Autoconf 2.54, so this conditional
+# definition can be removed once we require Autoconf 2.54 or later.
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP],
+[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep],
+   [if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi])
+ EGREP=$ac_cv_prog_egrep
+ AC_SUBST([EGREP])
+])])
+
+
+# AC_PATH_TOOL_PREFIX
+# -------------------
+# find a file program which can recognise shared library
+AC_DEFUN([AC_PATH_TOOL_PREFIX],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] |  ?:[\\/]*])
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="ifelse([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+])# AC_PATH_TOOL_PREFIX
+
+
+# AC_PATH_MAGIC
+# -------------
+# find a file program which can recognise a shared library
+AC_DEFUN([AC_PATH_MAGIC],
+[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])# AC_PATH_MAGIC
+
+
+# AC_PROG_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([AC_PROG_LD],
+[AC_ARG_WITH([gnu-ld],
+    [AC_HELP_STRING([--with-gnu-ld],
+	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test "$withval" = no || with_gnu_ld=yes],
+    [with_gnu_ld=no])
+AC_REQUIRE([LT_AC_PROG_SED])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by $CC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | ?:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])# AC_PROG_LD
+
+
+# AC_PROG_LD_GNU
+# --------------
+AC_DEFUN([AC_PROG_LD_GNU],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# AC_PROG_LD_GNU
+
+
+# AC_PROG_LD_RELOAD_FLAG
+# ----------------------
+# find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+AC_DEFUN([AC_PROG_LD_RELOAD_FLAG],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+  lt_cv_ld_reload_flag,
+  [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+])# AC_PROG_LD_RELOAD_FLAG
+
+
+# AC_DEPLIBS_CHECK_METHOD
+# -----------------------
+# how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
+[AC_CACHE_CHECK([how to recognise dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi4*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump'.
+  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | kfreebsd*-gnu)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case "$host_cpu" in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  case $host_cpu in
+  alpha*|hppa*|i*86|ia64*|m68*|mips*|powerpc*|sparc*|s390*|sh*|x86_64*)
+    lt_cv_deplibs_check_method=pass_all ;;
+  *)
+    # glibc up to 2.1.1 does not perform some relocations on ARM
+    # this will be overridden with pass_all, but let us keep it just in case
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;;
+  esac
+  lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+nto-qnx*)
+  lt_cv_deplibs_check_method=unknown
+  ;;
+
+openbsd*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object'
+  else
+    lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sco3.2v5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+])# AC_DEPLIBS_CHECK_METHOD
+
+
+# AC_PROG_NM
+# ----------
+# find the pathname to a BSD-compatible name lister
+AC_DEFUN([AC_PROG_NM],
+[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    tmp_nm="$ac_dir/${ac_tool_prefix}nm"
+    if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      # Tru64's nm complains that /dev/null is an invalid object file
+      case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+      */dev/null* | *'Invalid file or object type'*)
+	lt_cv_path_NM="$tmp_nm -B"
+	break
+        ;;
+      *)
+	case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	*/dev/null*)
+	  lt_cv_path_NM="$tmp_nm -p"
+	  break
+	  ;;
+	*)
+	  lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	  continue # so that we can try to find one that supports BSD flags
+	  ;;
+	esac
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+  test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi])
+NM="$lt_cv_path_NM"
+])# AC_PROG_NM
+
+
+# AC_CHECK_LIBM
+# -------------
+# check for math library
+AC_DEFUN([AC_CHECK_LIBM],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
+  # These system don't have libm, or don't need it
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
+  ;;
+esac
+])# AC_CHECK_LIBM
+
+
+# AC_LIBLTDL_CONVENIENCE([DIRECTORY])
+# -----------------------------------
+# sets LIBLTDL to the link flags for the libltdl convenience library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-convenience to the configure arguments.  Note that LIBLTDL
+# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called.  If
+# DIRECTORY is not provided, it is assumed to be `libltdl'.  LIBLTDL will
+# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with
+# '${top_srcdir}/' (note the single quotes!).  If your package is not
+# flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  case $enable_ltdl_convenience in
+  no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+  "") enable_ltdl_convenience=yes
+      ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+  esac
+  LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+  LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+  # For backwards non-gettext consistent compatibility...
+  INCLTDL="$LTDLINCL"
+])# AC_LIBLTDL_CONVENIENCE
+
+
+# AC_LIBLTDL_INSTALLABLE([DIRECTORY])
+# -----------------------------------
+# sets LIBLTDL to the link flags for the libltdl installable library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-install to the configure arguments.  Note that LIBLTDL
+# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called.  If
+# DIRECTORY is not provided and an installed libltdl is not found, it is
+# assumed to be `libltdl'.  LIBLTDL will be prefixed with '${top_builddir}/'
+# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single
+# quotes!).  If your package is not flat and you're not using automake,
+# define top_builddir and top_srcdir appropriately in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  AC_CHECK_LIB(ltdl, lt_dlinit,
+  [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+  [if test x"$enable_ltdl_install" = xno; then
+     AC_MSG_WARN([libltdl not installed, but installation disabled])
+   else
+     enable_ltdl_install=yes
+   fi
+  ])
+  if test x"$enable_ltdl_install" = x"yes"; then
+    ac_configure_args="$ac_configure_args --enable-ltdl-install"
+    LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+    LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+  else
+    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+    LIBLTDL="-lltdl"
+    LTDLINCL=
+  fi
+  # For backwards non-gettext consistent compatibility...
+  INCLTDL="$LTDLINCL"
+])# AC_LIBLTDL_INSTALLABLE
+
+
+# AC_LIBTOOL_CXX
+# --------------
+# enable support for C++ libraries
+AC_DEFUN([AC_LIBTOOL_CXX],
+[AC_REQUIRE([_LT_AC_LANG_CXX])
+])# AC_LIBTOOL_CXX
+
+
+# _LT_AC_LANG_CXX
+# ---------------
+AC_DEFUN([_LT_AC_LANG_CXX],
+[AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([AC_PROG_CXXCPP])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX])
+])# _LT_AC_LANG_CXX
+
+
+# AC_LIBTOOL_F77
+# --------------
+# enable support for Fortran 77 libraries
+AC_DEFUN([AC_LIBTOOL_F77],
+[AC_REQUIRE([_LT_AC_LANG_F77])
+])# AC_LIBTOOL_F77
+
+
+# _LT_AC_LANG_F77
+# ---------------
+AC_DEFUN([_LT_AC_LANG_F77],
+[AC_REQUIRE([AC_PROG_F77])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77])
+])# _LT_AC_LANG_F77
+
+
+# AC_LIBTOOL_GCJ
+# --------------
+# enable support for GCJ libraries
+AC_DEFUN([AC_LIBTOOL_GCJ],
+[AC_REQUIRE([_LT_AC_LANG_GCJ])
+])# AC_LIBTOOL_GCJ
+
+
+# _LT_AC_LANG_GCJ
+# ---------------
+AC_DEFUN([_LT_AC_LANG_GCJ],
+[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[],
+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[],
+    [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[],
+      [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])],
+	 [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])],
+	   [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ])
+])# _LT_AC_LANG_GCJ
+
+
+# AC_LIBTOOL_RC
+# --------------
+# enable support for Windows resource files
+AC_DEFUN([AC_LIBTOOL_RC],
+[AC_REQUIRE([LT_AC_PROG_RC])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC])
+])# AC_LIBTOOL_RC
+
+
+# AC_LIBTOOL_LANG_C_CONFIG
+# ------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG])
+AC_DEFUN([_LT_AC_LANG_C_CONFIG],
+[lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}\n'
+
+_LT_AC_SYS_COMPILER
+
+#
+# Check for any special shared library compilation flags.
+#
+_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)=
+if test "$GCC" = no; then
+  case $host_os in
+  sco3.2v5*)
+    _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf'
+    ;;
+  esac
+fi
+if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then
+  AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries])
+  if echo "$old_CC $old_CFLAGS " | grep "[[ 	]]$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[ 	]]" >/dev/null; then :
+  else
+    AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure])
+    _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no
+  fi
+fi
+
+
+#
+# Check to make sure the static flag actually works.
+#
+AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works],
+  _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1),
+  $_LT_AC_TAGVAR(lt_prog_compiler_static, $1),
+  [],
+  [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=])
+
+
+AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+AC_LIBTOOL_DLOPEN_SELF($1)
+
+# Report which librarie types wil actually be built
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4* | aix5*)
+  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+    test "$enable_shared" = yes && enable_static=no
+  fi
+  ;;
+  darwin* | rhapsody*)
+  if test "$GCC" = yes; then
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    case "$host_os" in
+    rhapsody* | darwin1.[[012]])
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress'
+      ;;
+    *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+      	_LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[[012]])
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+      ;;
+    esac
+    output_verbose_link_cmd='echo'
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring'
+    _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+    # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag  -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    _LT_AC_TAGVAR(hardcode_direct, $1)=no
+    _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+    _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience'
+    _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+  else
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+  fi
+    ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_C_CONFIG
+
+
+# AC_LIBTOOL_LANG_CXX_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)])
+AC_DEFUN([_LT_AC_LANG_CXX_CONFIG],
+[AC_LANG_PUSH(C++)
+AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([AC_PROG_CXXCPP])
+
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_AC_TAGVAR(allow_undefined_flag, $1)=
+_LT_AC_TAGVAR(always_export_symbols, $1)=no
+_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_direct, $1)=no
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+_LT_AC_TAGVAR(hardcode_automatic, $1)=no
+_LT_AC_TAGVAR(module_cmds, $1)=
+_LT_AC_TAGVAR(module_expsym_cmds, $1)=
+_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_AC_TAGVAR(no_undefined_flag, $1)=
+_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Dependencies to place before and after the object being linked:
+_LT_AC_TAGVAR(predep_objects, $1)=
+_LT_AC_TAGVAR(postdep_objects, $1)=
+_LT_AC_TAGVAR(predeps, $1)=
+_LT_AC_TAGVAR(postdeps, $1)=
+_LT_AC_TAGVAR(compiler_lib_search_path, $1)=
+
+# Source file extension for C++ test sources.
+ac_ext=cc
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_LD=$LD
+lt_save_GCC=$GCC
+GCC=$GXX
+lt_save_with_gnu_ld=$with_gnu_ld
+lt_save_path_LD=$lt_cv_path_LD
+if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+  lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+else
+  unset lt_cv_prog_gnu_ld
+fi
+if test -n "${lt_cv_path_LDCXX+set}"; then
+  lt_cv_path_LD=$lt_cv_path_LDCXX
+else
+  unset lt_cv_path_LD
+fi
+test -z "${LDCXX+set}" || LD=$LDCXX
+CC=${CXX-"c++"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'`
+
+# We don't want -fno-exception wen compiling C++ code, so set the
+# no_builtin_flag separately
+if test "$GXX" = yes; then
+  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+else
+  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+fi
+
+if test "$GXX" = yes; then
+  # Set up default GNU C++ configuration
+
+  AC_PROG_LD
+
+  # Check if GNU C++ uses GNU ld as the underlying linker, since the
+  # archiving commands below assume that GNU ld is being used.
+  if test "$with_gnu_ld" = yes; then
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+    #     investigate it a little bit more. (MM)
+    wlarc='${wl}'
+
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if eval "`$CC -print-prog-name=ld` --help 2>&1" | \
+	grep 'no-whole-archive' > /dev/null; then
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    with_gnu_ld=no
+    wlarc=
+
+    # A generic and very simple default shared library creation
+    # command for GNU C++ for the case where it uses the native
+    # linker, instead of GNU ld.  If possible, this setting should
+    # overridden to take advantage of the native linker features on
+    # the platform it is being used on.
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+  fi
+
+  # Commands to make compiler produce verbose output that lists
+  # what "hidden" libraries, object files and flags are used when
+  # linking a shared library.
+  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+else
+  GXX=no
+  with_gnu_ld=no
+  wlarc=
+fi
+
+# PORTME: fill in a description of your system's C++ link characteristics
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+_LT_AC_TAGVAR(ld_shlibs, $1)=yes
+case $host_os in
+  aix3*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  aix4* | aix5*)
+    if test "$host_cpu" = ia64; then
+      # On IA64, the linker does run time linking by default, so we don't
+      # have to do anything special.
+      aix_use_runtimelinking=no
+      exp_sym_flag='-Bexport'
+      no_entry_flag=""
+    else
+      aix_use_runtimelinking=no
+
+      # Test if we are trying to use run time linking or normal
+      # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+      # need to do runtime linking.
+      case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
+	for ld_flag in $LDFLAGS; do
+	  case $ld_flag in
+	  *-brtl*)
+	    aix_use_runtimelinking=yes
+	    break
+	    ;;
+	  esac
+	done
+      esac
+
+      exp_sym_flag='-bexport'
+      no_entry_flag='-bnoentry'
+    fi
+
+    # When large executables or shared objects are built, AIX ld can
+    # have problems creating the table of contents.  If linking a library
+    # or program results in "error TOC overflow" add -mminimal-toc to
+    # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+    # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+    _LT_AC_TAGVAR(archive_cmds, $1)=''
+    _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+    _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+    if test "$GXX" = yes; then
+      case $host_os in aix4.[012]|aix4.[012].*)
+      # We only want to do this on AIX 4.2 and lower, the check
+      # below for broken collect2 doesn't work under 4.3+
+	collect2name=`${CC} -print-prog-name=collect2`
+	if test -f "$collect2name" && \
+	   strings "$collect2name" | grep resolve_lib_name >/dev/null
+	then
+	  # We have reworked collect2
+	  _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+	else
+	  # We have old collect2
+	  _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+	fi
+      esac
+      shared_flag='-shared'
+    else
+      # not using gcc
+      if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	shared_flag='-G'
+      else
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag='${wl}-G'
+	else
+	  shared_flag='${wl}-bM:SRE'
+	fi
+      fi
+    fi
+
+    # It seems that -bexpall does not export symbols beginning with
+    # underscore (_), so it is better to generate a list of symbols to export.
+    _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+    if test "$aix_use_runtimelinking" = yes; then
+      # Warning - without using the other runtime loading flags (-brtl),
+      # -berok will link without error, but may produce a broken library.
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
+      # Determine the default libpath from the value encoded in an empty executable.
+      _LT_AC_SYS_LIBPATH_AIX
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+     else
+      if test "$host_cpu" = ia64; then
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+      else
+	# Determine the default libpath from the value encoded in an empty executable.
+	_LT_AC_SYS_LIBPATH_AIX
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	# Warning - without using the other run time loading flags,
+	# -berok will link without error, but may produce a broken library.
+	_LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	# -bexpall does not export symbols beginning with underscore (_)
+	_LT_AC_TAGVAR(always_export_symbols, $1)=yes
+	# Exported symbols can be pulled into shared objects from archives
+	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' '
+	_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+	# This is similar to how AIX traditionally builds it's shared libraries.
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+      fi
+    fi
+    ;;
+  chorus*)
+    case $cc_basename in
+      *)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+    esac
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+    # as there is no search path for DLLs.
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+    _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+    _LT_AC_TAGVAR(always_export_symbols, $1)=no
+    _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+    if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+      # If the export-symbols file already is a .def file (1st line
+      # is EXPORTS), use it as is; otherwise, prepend...
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	cp $export_symbols $output_objdir/$soname.def;
+      else
+	echo EXPORTS > $output_objdir/$soname.def;
+	cat $export_symbols >> $output_objdir/$soname.def;
+      fi~
+      $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+    else
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    fi
+  ;;
+
+  darwin* | rhapsody*)
+  if test "$GXX" = yes; then
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    case "$host_os" in
+    rhapsody* | darwin1.[[012]])
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress'
+      ;;
+    *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+      	_LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[[012]])
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+      ;;
+    esac
+    lt_int_apple_cc_single_mod=no
+    output_verbose_link_cmd='echo'
+    if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
+      lt_int_apple_cc_single_mod=yes
+    fi
+    if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+    else
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+    fi
+    _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+
+    # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+    if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    else
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    _LT_AC_TAGVAR(hardcode_direct, $1)=no
+    _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+    _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience'
+    _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+  else
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+  fi
+    ;;
+
+  dgux*)
+    case $cc_basename in
+      ec++)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      ghcx)
+	# Green Hills C++ Compiler
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+    esac
+    ;;
+  freebsd[12]*)
+    # C++ shared libraries reported to be fairly broken before switch to ELF
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  freebsd-elf*)
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    ;;
+  freebsd* | kfreebsd*-gnu)
+    # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+    # conventions
+    _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+    ;;
+  gnu*)
+    ;;
+  hpux9*)
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+    _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+    _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+				# but as the default
+				# location of the library.
+
+    case $cc_basename in
+    CC)
+      # FIXME: insert proper C++ library support
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    aCC)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      #
+      # There doesn't appear to be a way to prevent this compiler from
+      # explicitly linking system object files so we need to strip them
+      # from the output so that they don't get included in the library
+      # dependencies.
+      output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+      ;;
+    *)
+      if test "$GXX" = yes; then
+        _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+        # FIXME: insert proper C++ library support
+        _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+    ;;
+  hpux10*|hpux11*)
+    if test $with_gnu_ld = no; then
+      case "$host_cpu" in
+      hppa*64*)
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+        ;;
+      ia64*)
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+        ;;
+      *)
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+        ;;
+      esac
+    fi
+    case "$host_cpu" in
+    hppa*64*)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+    ia64*)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+					      # but as the default
+					      # location of the library.
+      ;;
+    *)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+					      # but as the default
+					      # location of the library.
+      ;;
+    esac
+
+    case $cc_basename in
+      CC)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      aCC)
+	case "$host_cpu" in
+	hppa*64*|ia64*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+	  ;;
+	*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	  ;;
+	esac
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	;;
+      *)
+	if test "$GXX" = yes; then
+	  if test $with_gnu_ld = no; then
+	    case "$host_cpu" in
+	    ia64*|hppa*64*)
+	      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+	      ;;
+	    *)
+	      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      ;;
+	    esac
+	  fi
+	else
+	  # FIXME: insert proper C++ library support
+	  _LT_AC_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+    esac
+    ;;
+  irix5* | irix6*)
+    case $cc_basename in
+      CC)
+	# SGI C++
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+
+	# Archives containing C++ object files must be created using
+	# "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	# necessary to make sure instantiated templates are included
+	# in the archive.
+	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	;;
+      *)
+	if test "$GXX" = yes; then
+	  if test "$with_gnu_ld" = no; then
+	    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+	  else
+	    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
+	  fi
+	fi
+	_LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+	;;
+    esac
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+    ;;
+  linux*)
+    case $cc_basename in
+      KCC)
+	# Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	# KCC will only create a shared library if the output file
+	# ends with ".so" (or ".sl" for HP-UX), so rename the library
+	# to its proper name (with version) after linking.
+	_LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir'
+	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+	# Archives containing C++ object files must be created using
+	# "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+	;;
+      icpc)
+	# Intel C++
+	with_gnu_ld=yes
+	_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	;;
+      cxx)
+	# Compaq C++
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+	runpath_var=LD_RUN_PATH
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	;;
+    esac
+    ;;
+  lynxos*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  m88k*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  mvs*)
+    case $cc_basename in
+      cxx)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+    esac
+    ;;
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+      wlarc=
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    fi
+    # Workaround some broken pre-1.5 toolchains
+    output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+    ;;
+  osf3*)
+    case $cc_basename in
+      KCC)
+	# Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	# KCC will only create a shared library if the output file
+	# ends with ".so" (or ".sl" for HP-UX), so rename the library
+	# to its proper name (with version) after linking.
+	_LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	# Archives containing C++ object files must be created using
+	# "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+
+	;;
+      RCC)
+	# Rational C++ 2.4.1
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      cxx)
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	;;
+      *)
+	if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	  _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	  # Commands to make compiler produce verbose output that lists
+	  # what "hidden" libraries, object files and flags are used when
+	  # linking a shared library.
+	  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+	else
+	  # FIXME: insert proper C++ library support
+	  _LT_AC_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+    esac
+    ;;
+  osf4* | osf5*)
+    case $cc_basename in
+      KCC)
+	# Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	# KCC will only create a shared library if the output file
+	# ends with ".so" (or ".sl" for HP-UX), so rename the library
+	# to its proper name (with version) after linking.
+	_LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	# Archives containing C++ object files must be created using
+	# the KAI C++ compiler.
+	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs'
+	;;
+      RCC)
+	# Rational C++ 2.4.1
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      cxx)
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+	  echo "-hidden">> $lib.exp~
+	  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp  `test -n "$verstring" && echo -set_version	$verstring` -update_registry $objdir/so_locations -o $lib~
+	  $rm $lib.exp'
+
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+	_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	;;
+      *)
+	if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	  _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	 _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	  # Commands to make compiler produce verbose output that lists
+	  # what "hidden" libraries, object files and flags are used when
+	  # linking a shared library.
+	  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+	else
+	  # FIXME: insert proper C++ library support
+	  _LT_AC_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+    esac
+    ;;
+  psos*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  sco*)
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    case $cc_basename in
+      CC)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+    esac
+    ;;
+  sunos4*)
+    case $cc_basename in
+      CC)
+	# Sun C++ 4.x
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      lcc)
+	# Lucid
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+    esac
+    ;;
+  solaris*)
+    case $cc_basename in
+      CC)
+	# Sun C++ 4.2, 5.x and Centerline C++
+	_LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+	$CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+	case $host_os in
+	  solaris2.[0-5] | solaris2.[0-5].*) ;;
+	  *)
+	    # The C++ compiler is used as linker so we must use $wl
+	    # flag to pass the commands to the underlying system
+	    # linker.
+	    # Supported since Solaris 2.6 (maybe 2.5.1?)
+	    _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	    ;;
+	esac
+	_LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[[LR]]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+	# Archives containing C++ object files must be created using
+	# "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	# necessary to make sure instantiated templates are included
+	# in the archive.
+	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	;;
+      gcx)
+	# Green Hills C++ Compiler
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+	# The C++ compiler must be used to create the archive.
+	_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	;;
+      *)
+	# GNU C++ compiler with Solaris linker
+	if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	  _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+	  if $CC --version | grep -v '^2\.7' > /dev/null; then
+	    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+		$CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+	  else
+	    # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	    # platform.
+	    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+		$CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+	  fi
+
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+	fi
+	;;
+    esac
+    ;;
+  sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*)
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    ;;
+  tandem*)
+    case $cc_basename in
+      NCC)
+	# NonStop-UX NCC 3.20
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	;;
+    esac
+    ;;
+  vxworks*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  *)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+esac
+AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_AC_TAGVAR(GCC, $1)="$GXX"
+_LT_AC_TAGVAR(LD, $1)="$LD"
+
+AC_LIBTOOL_POSTDEP_PREDEP($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+AC_LIBTOOL_DLOPEN_SELF($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC=$lt_save_CC
+LDCXX=$LD
+LD=$lt_save_LD
+GCC=$lt_save_GCC
+with_gnu_ldcxx=$with_gnu_ld
+with_gnu_ld=$lt_save_with_gnu_ld
+lt_cv_path_LDCXX=$lt_cv_path_LD
+lt_cv_path_LD=$lt_save_path_LD
+lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+])# AC_LIBTOOL_LANG_CXX_CONFIG
+
+# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME])
+# ------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library.  It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+ifelse([$1],[],[cat > conftest.$ac_ext <<EOF
+int a;
+void foo (void) { a = 0; }
+EOF
+],[$1],[CXX],[cat > conftest.$ac_ext <<EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+EOF
+],[$1],[F77],[cat > conftest.$ac_ext <<EOF
+      subroutine foo
+      implicit none
+      integer*4 a
+      a=0
+      return
+      end
+EOF
+],[$1],[GCJ],[cat > conftest.$ac_ext <<EOF
+public class foo {
+  private int a;
+  public void bar (void) {
+    a = 0;
+  }
+};
+EOF
+])
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  # The `*' in the case matches for architectures that use `case' in
+  # $output_verbose_cmd can trigger glob expansion during the loop
+  # eval without this substitution.
+  output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`"
+
+  for p in `eval $output_verbose_link_cmd`; do
+    case $p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" \
+	  || test $p = "-R"; then
+	 prev=$p
+	 continue
+       else
+	 prev=
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 case $p in
+	 -L* | -R*)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$_LT_AC_TAGVAR(compiler_lib_search_path, $1)"; then
+	     _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+	   else
+	     _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${_LT_AC_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$_LT_AC_TAGVAR(postdeps, $1)"; then
+	   _LT_AC_TAGVAR(postdeps, $1)="${prev}${p}"
+	 else
+	   _LT_AC_TAGVAR(postdeps, $1)="${_LT_AC_TAGVAR(postdeps, $1)} ${prev}${p}"
+	 fi
+       fi
+       ;;
+
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 if test -z "$_LT_AC_TAGVAR(predep_objects, $1)"; then
+	   _LT_AC_TAGVAR(predep_objects, $1)="$p"
+	 else
+	   _LT_AC_TAGVAR(predep_objects, $1)="$_LT_AC_TAGVAR(predep_objects, $1) $p"
+	 fi
+       else
+	 if test -z "$_LT_AC_TAGVAR(postdep_objects, $1)"; then
+	   _LT_AC_TAGVAR(postdep_objects, $1)="$p"
+	 else
+	   _LT_AC_TAGVAR(postdep_objects, $1)="$_LT_AC_TAGVAR(postdep_objects, $1) $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$rm -f confest.$objext
+
+case " $_LT_AC_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+])# AC_LIBTOOL_POSTDEP_PREDEP
+
+# AC_LIBTOOL_LANG_F77_CONFIG
+# ------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG], [_LT_AC_LANG_F77_CONFIG(F77)])
+AC_DEFUN([_LT_AC_LANG_F77_CONFIG],
+[AC_REQUIRE([AC_PROG_F77])
+AC_LANG_PUSH(Fortran 77)
+
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_AC_TAGVAR(allow_undefined_flag, $1)=
+_LT_AC_TAGVAR(always_export_symbols, $1)=no
+_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_direct, $1)=no
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+_LT_AC_TAGVAR(hardcode_automatic, $1)=no
+_LT_AC_TAGVAR(module_cmds, $1)=
+_LT_AC_TAGVAR(module_expsym_cmds, $1)=
+_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_AC_TAGVAR(no_undefined_flag, $1)=
+_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="      subroutine t\n      return\n      end\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="      program t\n      end\n"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${F77-"f77"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'`
+
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+aix4* | aix5*)
+  test "$enable_shared" = yes && enable_static=no
+  ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_AC_TAGVAR(GCC, $1)="$G77"
+_LT_AC_TAGVAR(LD, $1)="$LD"
+
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_F77_CONFIG
+
+
+# AC_LIBTOOL_LANG_GCJ_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG], [_LT_AC_LANG_GCJ_CONFIG(GCJ)])
+AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG],
+[AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${GCJ-"gcj"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+
+AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+AC_LIBTOOL_DLOPEN_SELF($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_GCJ_CONFIG
+
+
+# AC_LIBTOOL_LANG_RC_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the Windows resource compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG], [_LT_AC_LANG_RC_CONFIG(RC)])
+AC_DEFUN([_LT_AC_LANG_RC_CONFIG],
+[AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${RC-"windres"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_RC_CONFIG
+
+
+# AC_LIBTOOL_CONFIG([TAGNAME])
+# ----------------------------
+# If TAGNAME is not passed, then create an initial libtool script
+# with a default configuration from the untagged config vars.  Otherwise
+# add code to config.status for appending the configuration named by
+# TAGNAME from the matching tagged config vars.
+AC_DEFUN([AC_LIBTOOL_CONFIG],
+[# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    _LT_AC_TAGVAR(compiler, $1) \
+    _LT_AC_TAGVAR(CC, $1) \
+    _LT_AC_TAGVAR(LD, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_static, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) \
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1) \
+    _LT_AC_TAGVAR(thread_safe_flag_spec, $1) \
+    _LT_AC_TAGVAR(whole_archive_flag_spec, $1) \
+    _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) \
+    _LT_AC_TAGVAR(old_archive_cmds, $1) \
+    _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) \
+    _LT_AC_TAGVAR(predep_objects, $1) \
+    _LT_AC_TAGVAR(postdep_objects, $1) \
+    _LT_AC_TAGVAR(predeps, $1) \
+    _LT_AC_TAGVAR(postdeps, $1) \
+    _LT_AC_TAGVAR(compiler_lib_search_path, $1) \
+    _LT_AC_TAGVAR(archive_cmds, $1) \
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1) \
+    _LT_AC_TAGVAR(postinstall_cmds, $1) \
+    _LT_AC_TAGVAR(postuninstall_cmds, $1) \
+    _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) \
+    _LT_AC_TAGVAR(allow_undefined_flag, $1) \
+    _LT_AC_TAGVAR(no_undefined_flag, $1) \
+    _LT_AC_TAGVAR(export_symbols_cmds, $1) \
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) \
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) \
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1) \
+    _LT_AC_TAGVAR(hardcode_automatic, $1) \
+    _LT_AC_TAGVAR(module_cmds, $1) \
+    _LT_AC_TAGVAR(module_expsym_cmds, $1) \
+    _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \
+    _LT_AC_TAGVAR(exclude_expsyms, $1) \
+    _LT_AC_TAGVAR(include_expsyms, $1); do
+
+    case $var in
+    _LT_AC_TAGVAR(old_archive_cmds, $1) | \
+    _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) | \
+    _LT_AC_TAGVAR(archive_cmds, $1) | \
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1) | \
+    _LT_AC_TAGVAR(module_cmds, $1) | \
+    _LT_AC_TAGVAR(module_expsym_cmds, $1) | \
+    _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) | \
+    _LT_AC_TAGVAR(export_symbols_cmds, $1) | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\[$]0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\[$]0 --fallback-echo"[$]/[$]0 --fallback-echo"/'`
+    ;;
+  esac
+
+ifelse([$1], [],
+  [cfgfile="${ofile}T"
+  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+  $rm -f "$cfgfile"
+  AC_MSG_NOTICE([creating $ofile])],
+  [cfgfile="$ofile"])
+
+  cat <<__EOF__ >> "$cfgfile"
+ifelse([$1], [],
+[#! $SHELL
+
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+#
+# This file is part of GNU Libtool:
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="$SED -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+# The names of the tagged configurations supported by this script.
+available_tags=
+
+# ### BEGIN LIBTOOL CONFIG],
+[# ### BEGIN LIBTOOL TAG CONFIG: $tagname])
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# A language-specific compiler.
+CC=$lt_[]_LT_AC_TAGVAR(compiler, $1)
+
+# Is the compiler the GNU C compiler?
+with_gcc=$_LT_AC_TAGVAR(GCC, $1)
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_[]_LT_AC_TAGVAR(LD, $1)
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1)
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1)
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1)
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1)
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1)
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1)
+archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1)
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1)
+module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1)
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1)
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1)
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1)
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1)
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1)
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1)
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1)
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1)
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1)
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1)
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1)
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1)
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1)
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1)
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1)
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1)
+
+# Symbols that must always be exported.
+include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1)
+
+ifelse([$1],[],
+[# ### END LIBTOOL CONFIG],
+[# ### END LIBTOOL TAG CONFIG: $tagname])
+
+__EOF__
+
+ifelse([$1],[], [
+  case $host_os in
+  aix3*)
+    cat <<\EOF >> "$cfgfile"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" || \
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+])
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+fi
+])# AC_LIBTOOL_CONFIG
+
+
+# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------------------
+AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI],
+[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+
+_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+
+  AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+    lt_cv_prog_compiler_rtti_exceptions,
+    [-fno-rtti -fno-exceptions], [],
+    [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI
+
+
+# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+# ---------------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE],
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_PROG_NM])
+AC_REQUIRE([AC_OBJEXT])
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  if test "$host_cpu" = ia64; then
+    symcode='[[ABCDEGRST]]'
+  fi
+  lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+  lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  ;;
+irix* | nonstopux*)
+  symcode='[[BCDEGRST]]'
+  ;;
+osf*)
+  symcode='[[BCDEGQRST]]'
+  ;;
+solaris* | sysv5*)
+  symcode='[[BDRT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Write the raw and C identifiers.
+  lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ 	]]\($symcode$symcode*\)[[ 	]][[ 	]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if grep ' nm_test_var$' "$nlist" >/dev/null; then
+	if grep ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext'
+
+	  cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[[]] =
+{
+EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext
+	  cat <<\EOF >> conftest.$ac_ext
+  {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_save_LIBS="$LIBS"
+	  lt_save_CFLAGS="$CFLAGS"
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+	  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS="$lt_save_LIBS"
+	  CFLAGS="$lt_save_CFLAGS"
+	else
+	  echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+    fi
+  else
+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.$ac_ext >&5
+  fi
+  rm -f conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+
+
+# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME])
+# ---------------------------------------
+AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC],
+[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=
+
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+ ifelse([$1],[CXX],[
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+      ;;
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | os2* | pw32*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+	;;
+      *)
+	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+    *)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix4* | aix5*)
+	# All AIX code is PIC.
+	if test "$host_cpu" = ia64; then
+	  # AIX 5 now supports IA64 processor
+	  _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	else
+	  _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68)
+	  # Green Hills C++ Compiler
+	  # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++)
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  ghcx)
+	    # Green Hills C++ Compiler
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | kfreebsd*-gnu)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC)
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
+	    if test "$host_cpu" != ia64; then
+	      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	    fi
+	    ;;
+	  aCC)
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
+	    case "$host_cpu" in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC)
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux*)
+	case $cc_basename in
+	  KCC)
+	    # KAI C++ Compiler
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    ;;
+	  icpc)
+	    # Intel C++
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  cxx)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx)
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd*)
+	;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC)
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    ;;
+	  RCC)
+	    # Rational C++ 2.4.1
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  cxx)
+	    # Digital/Compaq C++
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      sco*)
+	case $cc_basename in
+	  CC)
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	    ;;
+	  gcx)
+	    # Green Hills C++ Compiler
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC)
+	    # Sun C++ 4.x
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  lcc)
+	    # Lucid
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC)
+	    # NonStop-UX NCC 3.20
+	    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      unixware*)
+	;;
+      vxworks*)
+	;;
+      *)
+	_LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+	;;
+    esac
+  fi
+],
+[
+  if test "$GCC" = yes; then
+    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+
+    *)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      else
+	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC (with -KPIC) is the default.
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    newsos6)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    linux*)
+      case $CC in
+      icc* | ecc*)
+	_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      ccc*)
+        _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        # All Alpha code is PIC.
+        _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # All OSF/1 code is PIC.
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    sco3.2v5*)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn'
+      ;;
+
+    solaris*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sunos4*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+	_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    uts4*)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *)
+      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+    esac
+  fi
+])
+AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)])
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then
+  AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works],
+    _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1),
+    [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [],
+    [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in
+     "" | " "*) ;;
+     *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+     esac],
+    [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+     _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+case "$host_os" in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+    ;;
+  *)
+    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])"
+    ;;
+esac
+])
+
+
+# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME])
+# ------------------------------------
+# See if the linker supports building shared libraries.
+AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS],
+[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ifelse([$1],[CXX],[
+  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  case $host_os in
+  aix4* | aix5*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+    else
+      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+  ;;
+  cygwin* | mingw*)
+    _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  *)
+    _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  esac
+],[
+  runpath_var=
+  _LT_AC_TAGVAR(allow_undefined_flag, $1)=
+  _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+  _LT_AC_TAGVAR(archive_cmds, $1)=
+  _LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+  _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)=
+  _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+  _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+  _LT_AC_TAGVAR(thread_safe_flag_spec, $1)=
+  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+  _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+  _LT_AC_TAGVAR(hardcode_direct, $1)=no
+  _LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+  _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+  _LT_AC_TAGVAR(hardcode_automatic, $1)=no
+  _LT_AC_TAGVAR(module_cmds, $1)=
+  _LT_AC_TAGVAR(module_expsym_cmds, $1)=
+  _LT_AC_TAGVAR(always_export_symbols, $1)=no
+  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  _LT_AC_TAGVAR(include_expsyms, $1)=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+
+      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+      # as there is no search path for DLLs.
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_AC_TAGVAR(always_export_symbols, $1)=no
+      _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000  ${wl}--out-implib,$lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris* | sysv5*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+	cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    sunos4*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+  linux*)
+    if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_AC_TAGVAR(archive_cmds, $1)="$tmp_archive_cmds"
+      supports_anon_versioning=no
+      case `$LD -v 2>/dev/null` in
+        *\ [01].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+        *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+        *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+        *\ 2.11.*) ;; # other 2.11 versions
+        *) supports_anon_versioning=yes ;;
+      esac
+      if test $supports_anon_versioning = yes; then
+        _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~
+cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+$echo "local: *; };" >> $output_objdir/$libname.ver~
+        $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+      else
+        _LT_AC_TAGVAR(archive_expsym_cmds, $1)="$tmp_archive_cmds"
+      fi
+    else
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    fi
+    ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+
+    if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = yes; then
+      runpath_var=LD_RUN_PATH
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+ 	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+  	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+      fi
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      if test "$GCC" = yes && test -z "$link_static_flag"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	_LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+	  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+	else
+	  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
+	  for ld_flag in $LDFLAGS; do
+  	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+  	    aix_use_runtimelinking=yes
+  	    break
+  	  fi
+	  done
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      _LT_AC_TAGVAR(archive_cmds, $1)=''
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[012]|aix4.[012].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" && \
+  	   strings "$collect2name" | grep resolve_lib_name >/dev/null
+	  then
+  	  # We have reworked collect2
+  	  _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+	  else
+  	  # We have old collect2
+  	  _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+  	  # It fails to find uninstalled libraries when the uninstalled
+  	  # path is not listed in the libpath.  Setting hardcode_minus_L
+  	  # to unsupported forces relinking
+  	  _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+  	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+  	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+	esac
+	shared_flag='-shared'
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+  	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+  	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+  	if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+  	fi
+	fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       _LT_AC_SYS_LIBPATH_AIX
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+	if test "$host_cpu" = ia64; then
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	  _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an empty executable.
+	 _LT_AC_SYS_LIBPATH_AIX
+	 _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	  _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	  # -bexpall does not export symbols beginning with underscore (_)
+	  _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+	  # Exported symbols can be pulled into shared objects from archives
+	  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' '
+	  _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  # This is similar to how AIX traditionally builds it's shared libraries.
+	  _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      # see comment about different semantics on the GNU ld section
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    bsdi4*)
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true'
+      # FIXME: Should let the user specify the lib program.
+      _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path='`cygpath -w "$srcfile"`'
+      _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      ;;
+
+    darwin* | rhapsody*)
+    if test "$GXX" = yes ; then
+      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+      case "$host_os" in
+      rhapsody* | darwin1.[[012]])
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress'
+	;;
+      *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+      	_LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[[012]])
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+	;;
+      esac
+    	lt_int_apple_cc_single_mod=no
+    	output_verbose_link_cmd='echo'
+    	if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
+    	  lt_int_apple_cc_single_mod=yes
+    	fi
+    	if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+    	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+    	else
+        _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      fi
+      _LT_AC_TAGVAR(module_cmds, $1)='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+        if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+          _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        else
+          _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        fi
+          _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience'
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+    else
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    fi
+      ;;
+
+    dgux*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    freebsd1*)
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      ;;
+
+    hpux10* | hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case "$host_cpu" in
+	hppa*64*|ia64*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case "$host_cpu" in
+	hppa*64*|ia64*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  ;;
+	*)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	case "$host_cpu" in
+	hppa*64*)
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+	  _LT_AC_TAGVAR(hardcode_direct, $1)=no
+	  _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  ;;
+	ia64*)
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_AC_TAGVAR(hardcode_direct, $1)=no
+	  _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+	  ;;
+	*)
+	  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+	  _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    newsos6)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    openbsd*)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      else
+       case $host_os in
+	 openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+	   _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	   _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	   ;;
+	 *)
+	   _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	   _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	   ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      else
+	_LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+	$LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    sco3.2v5*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ;;
+
+    solaris*)
+      _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
+      if test "$GCC" = yes; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+	  $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+  	$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      case $host_os in
+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+	_LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;;
+      esac
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+	  _LT_AC_TAGVAR(hardcode_direct, $1)=no
+        ;;
+	motorola)
+	  _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4.3*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	_LT_AC_TAGVAR(ld_shlibs, $1)=yes
+      fi
+      ;;
+
+    sysv4.2uw2*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      hardcode_runpath_var=yes
+      runpath_var=LD_RUN_PATH
+      ;;
+
+   sysv5OpenUNIX8* | sysv5UnixWare7* |  sysv5uw[[78]]* | unixware7*)
+      _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text'
+      if test "$GCC" = yes; then
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      runpath_var='LD_RUN_PATH'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv5*)
+      _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
+      # $CC -shared without GNU ld will not create a library from C++
+      # object files and a static libstdc++, better avoid it by now
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+  		$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+      ;;
+
+    uts4*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    esac
+  fi
+])
+AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+  # Assume -lc should be added
+  _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $_LT_AC_TAGVAR(archive_cmds, $1) in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1)
+        _LT_AC_TAGVAR(allow_undefined_flag, $1)=
+        if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1)
+        then
+	  _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+        else
+	  _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+        fi
+        _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)])
+      ;;
+    esac
+  fi
+  ;;
+esac
+])# AC_LIBTOOL_PROG_LD_SHLIBS
+
+
+# _LT_AC_FILE_LTDLL_C
+# -------------------
+# Be careful that the start marker always follows a newline.
+AC_DEFUN([_LT_AC_FILE_LTDLL_C], [
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# #  ifdef __CYGWIN32__
+# #    define __CYGWIN__ __CYGWIN32__
+# #  endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+#   __hDllInstance_base = hInst;
+#   return TRUE;
+# }
+# /* ltdll.c ends here */
+])# _LT_AC_FILE_LTDLL_C
+
+
+# _LT_AC_TAGVAR(VARNAME, [TAGNAME])
+# ---------------------------------
+AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])])
+
+
+# old names
+AC_DEFUN([AM_PROG_LIBTOOL],   [AC_PROG_LIBTOOL])
+AC_DEFUN([AM_ENABLE_SHARED],  [AC_ENABLE_SHARED($@)])
+AC_DEFUN([AM_ENABLE_STATIC],  [AC_ENABLE_STATIC($@)])
+AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+AC_DEFUN([AM_PROG_LD],        [AC_PROG_LD])
+AC_DEFUN([AM_PROG_NM],        [AC_PROG_NM])
+
+# This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])
+
+AC_DEFUN([LT_AC_PROG_GCJ],
+[AC_CHECK_TOOL(GCJ, gcj, no)
+  test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+  AC_SUBST(GCJFLAGS)
+])
+
+AC_DEFUN([LT_AC_PROG_RC],
+[AC_CHECK_TOOL(RC, windres, no)
+])
+
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+# LT_AC_PROG_SED
+# --------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+AC_DEFUN([LT_AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && break
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+SED=$lt_cv_path_SED
+])
+AC_MSG_RESULT([$SED])
+])
+
+#                                                        -*- Autoconf -*-
+# Copyright (C) 2002, 2003  Free Software Foundation, Inc.
+# Generated from amversion.in; do not edit by hand.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.8"])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION so it can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+	 [AM_AUTOMAKE_VERSION([1.8.3])])
+
+# AM_AUX_DIR_EXPAND
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL                                              -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 6
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+	[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])
+AC_SUBST([$1_FALSE])
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.])
+fi])])
+
+# serial 7						-*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+# Free Software Foundation, Inc.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC,   [depcc="$CC"   am_compiler_list=],
+       [$1], CXX,  [depcc="$CXX"  am_compiler_list=],
+       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+       [$1], GCJ,  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                   [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_$1_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+  fi
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    case $depmode in
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    none) break ;;
+    esac
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.
+    if depmode=$depmode \
+       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored.
+      if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
+        am_cv_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])
+])
+
+# Generate code to set up dependency tracking.   -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+#serial 2
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+  # Strip MF so we end up with the name of the file.
+  mf=`echo "$mf" | sed -e 's/:.*$//'`
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+    dirpart=`AS_DIRNAME("$mf")`
+  else
+    continue
+  fi
+  grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
+  # Extract the definition of DEP_FILES from the Makefile without
+  # running `make'.
+  DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+  test -z "$DEPDIR" && continue
+  # When using ansi2knr, U may be empty or an underscore; expand it
+  U=`sed -n 's/^U = //p' < "$mf"`
+  test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+  # We invoke sed twice because it is the simplest approach to
+  # changing $(DEPDIR) to its actual value in the expansion.
+  for file in `sed -n '
+    /^DEP_FILES = .*\\\\$/ {
+      s/^DEP_FILES = //
+      :loop
+	s/\\\\$//
+	p
+	n
+	/\\\\$/ b loop
+      p
+    }
+    /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+       sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+    # Make sure the directory exists.
+    test -f "$dirpart/$file" && continue
+    fdir=`AS_DIRNAME(["$file"])`
+    AS_MKDIR_P([$dirpart/$fdir])
+    # echo "creating $dirpart/$file"
+    echo '# dummy' > "$dirpart/$file"
+  done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 7
+
+# AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
+AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
+
+# Do all the work for Automake.                            -*- Autoconf -*-
+
+# This macro actually does too much some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 11
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.50])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+   test -f $srcdir/config.status; then
+  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_MISSING_PROG(AMTAR, tar)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+                  [_AM_DEPENDENCIES(CC)],
+                  [define([AC_PROG_CC],
+                          defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+                  [_AM_DEPENDENCIES(CXX)],
+                  [define([AC_PROG_CXX],
+                          defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $1 | $1:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+#                                                          -*- Autoconf -*-
+# Copyright (C) 2003  Free Software Foundation, Inc.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 1
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Check to see how 'make' treats includes.	-*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+   am__include=include
+   am__quote=
+   _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+      am__include=.include
+      am__quote="\""
+      _am_result=BSD
+   fi
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+#  -*- Autoconf -*-
+
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
+
+# Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
+# created by `make install' are always world readable, even if the
+# installer happens to have an overly restrictive umask (e.g. 077).
+# This was a mistake.  There are at least two reasons why we must not
+# use `-m 0755':
+#   - it causes special bits like SGID to be ignored,
+#   - it may be too restrictive (some setups expect 775 directories).
+#
+# Do not use -m 0755 and let people choose whatever they expect by
+# setting umask.
+#
+# We cannot accept any implementation of `mkdir' that recognizes `-p'.
+# Some implementations (such as Solaris 8's) are not thread-safe: if a
+# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
+# concurrently, both version can detect that a/ is missing, but only
+# one can create it and the other will error out.  Consequently we
+# restrict ourselves to GNU make (using the --version option ensures
+# this.)
+AC_DEFUN([AM_PROG_MKDIR_P],
+[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+  # Keeping the `.' argument allows $(mkdir_p) to be used without
+  # argument.  Indeed, we sometimes output rules like
+  #   $(mkdir_p) $(somedir)
+  # where $(somedir) is conditionally defined.
+  # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more
+  # expensive solution, as it forces Make to start a sub-shell.)
+  mkdir_p='mkdir -p -- .'
+else
+  # On NextStep and OpenStep, the `mkdir' command does not
+  # recognize any option.  It will interpret all options as
+  # directories to create, and then abort because `.' already
+  # exists.
+  for d in ./-p ./--version;
+  do
+    test -d $d && rmdir $d
+  done
+  # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+  if test -f "$ac_aux_dir/mkinstalldirs"; then
+    mkdir_p='$(mkinstalldirs)'
+  else
+    mkdir_p='$(install_sh) -d'
+  fi
+fi
+AC_SUBST([mkdir_p])])
+
+# Helper functions for option handling.                    -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003  Free Software Foundation, Inc.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+   if test "$[*]" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$[*]" != "X $srcdir/configure conftest.file" \
+      && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# AM_PROG_INSTALL_STRIP
+
+# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
Index: /branches/rel3/psModules/config.guess
===================================================================
--- /branches/rel3/psModules/config.guess	(revision 2163)
+++ /branches/rel3/psModules/config.guess	(revision 2163)
@@ -0,0 +1,1411 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2003-06-17'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+## for Red Hat Linux
+if test -f /etc/redhat-release ; then
+    VENDOR=redhat ;
+else
+    VENDOR= ;
+fi
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    pmax:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mipseb-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    alpha:OSF1:*:*)
+	if test $UNAME_RELEASE = "V4.0"; then
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+	fi
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha*:OpenVMS:*:*)
+	echo alpha-hp-vms
+	exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit 0 ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7 && exit 0 ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c \
+	  && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && exit 0
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit 0 ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    # avoid double evaluation of $set_cc_for_build
+	    test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    *:UNICOS/mp:*:*)
+	echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' 
+	exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*|*:GNU/FreeBSD:*:*)
+	# Determine whether the default compiler uses glibc.
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#if __GLIBC__ >= 2
+	LIBC=gnu
+	#else
+	LIBC=
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit 0 ;;
+    x86:Interix*:[34]*)
+	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+	exit 0 ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit 0 ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit 0 ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR:-unknown}-linux-gnu
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    ppc:Linux:*:*)
+	echo powerpc-${VENDOR:-unknown}-linux-gnu
+	exit 0 ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-${VENDOR:-unknown}-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-${VENDOR:-ibm}-linux-gnu
+	exit 0 ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    x86_64:Linux:*:*)
+	echo x86_64-${VENDOR:-unknown}-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit 0 ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	test x"${LIBC}" != x && echo "${UNAME_MACHINE}-${VENDOR:-pc}-linux-${LIBC}" && exit 0
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit 0 ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit 0 ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit 0 ;;
+    i*86:*:5:[78]*)
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit 0 ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit 0 ;;
+    M68*:*:R3V[567]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Darwin:*:*)
+	case `uname -p` in
+	    *86) UNAME_PROCESSOR=i686 ;;
+	    powerpc) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit 0 ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit 0 ;;
+    NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit 0 ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit 0 ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit 0 ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit 0 ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit 0 ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit 0 ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit 0 ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
Index: /branches/rel3/psModules/config.sub
===================================================================
--- /branches/rel3/psModules/config.sub	(revision 2163)
+++ /branches/rel3/psModules/config.sub	(revision 2163)
@@ -0,0 +1,1500 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2003-06-18'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k \
+	| m32r | m68000 | m68k | m88k | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| msp430 \
+	| ns16k | ns32k \
+	| openrisc | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| s390 | s390x \
+	| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* \
+	| bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* \
+	| m32r-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| msp430-* \
+	| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| s390-* | s390x-* \
+	| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+	| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+	| xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	mmix*)
+		basic_machine=mmix-knuth
+		os=-mmixware
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nv1)
+		basic_machine=nv1-cray
+		os=-unicosmp
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	or32 | or32-*)
+		basic_machine=or32-unknown
+		os=-coff
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparc | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+	c4x-* | tic4x-*)
+		os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
Index: /branches/rel3/psModules/configure
===================================================================
--- /branches/rel3/psModules/configure	(revision 2163)
+++ /branches/rel3/psModules/configure	(revision 2163)
@@ -0,0 +1,20514 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.57.
+#
+# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
+  ;;
+esac
+
+echo=${ECHO-echo}
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+       echo_test_string="`eval $cmd`" &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+    then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+   echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+   test "X$echo_testing_string" = "X$echo_test_string"; then
+  :
+else
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for dir in $PATH /usr/ucb; do
+    IFS="$lt_save_ifs"
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+	 test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running configure again with it.
+      ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+    else
+      # Try using printf.
+      echo='printf %s\n'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+	 echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+	 test "X$echo_testing_string" = "X$echo_test_string"; then
+	# Cool, printf works
+	:
+      elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+	   test "X$echo_testing_string" = 'X\t' &&
+	   echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+	export CONFIG_SHELL
+	SHELL="$CONFIG_SHELL"
+	export SHELL
+	echo="$CONFIG_SHELL $0 --fallback-echo"
+      elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+	   test "X$echo_testing_string" = 'X\t' &&
+	   echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	echo="$CONFIG_SHELL $0 --fallback-echo"
+      else
+	# maybe with a smaller string...
+	prev=:
+
+	for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+	  if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+	  then
+	    break
+	  fi
+	  prev="$cmd"
+	done
+
+	if test "$prev" != 'sed 50q "$0"'; then
+	  echo_test_string=`eval $prev`
+	  export echo_test_string
+	  exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+	else
+	  # Oops.  We lost completely, so just stick with echo.
+	  echo=echo
+	fi
+      fi
+    fi
+  fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+   ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+fi
+
+
+
+
+tagnames=${tagnames+${tagnames},}CXX
+
+tagnames=${tagnames+${tagnames},}F77
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="configure.in"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL GSL_CONFIG LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+              localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$0" : 'X\(//\)[^/]' \| \
+         X"$0" : 'X\(//\)$' \| \
+         X"$0" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+ac_env_CXX_set=${CXX+set}
+ac_env_CXX_value=$CXX
+ac_cv_env_CXX_set=${CXX+set}
+ac_cv_env_CXX_value=$CXX
+ac_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_env_CXXFLAGS_value=$CXXFLAGS
+ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_cv_env_CXXFLAGS_value=$CXXFLAGS
+ac_env_CXXCPP_set=${CXXCPP+set}
+ac_env_CXXCPP_value=$CXXCPP
+ac_cv_env_CXXCPP_set=${CXXCPP+set}
+ac_cv_env_CXXCPP_value=$CXXCPP
+ac_env_F77_set=${F77+set}
+ac_env_F77_value=$F77
+ac_cv_env_F77_set=${F77+set}
+ac_cv_env_F77_value=$F77
+ac_env_FFLAGS_set=${FFLAGS+set}
+ac_env_FFLAGS_value=$FFLAGS
+ac_cv_env_FFLAGS_set=${FFLAGS+set}
+ac_cv_env_FFLAGS_value=$FFLAGS
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors
+  --enable-shared[=PKGS]
+                          build shared libraries [default=yes]
+  --enable-static[=PKGS]
+                          build static libraries [default=yes]
+  --enable-fast-install[=PKGS]
+                          optimize for fast installation [default=yes]
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-pic              try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-tags[=TAGS]
+                          include additional configurations [automatic]
+  --with-psLib=DIR        Specify location of psLib files
+  --with-sla=DIR          Specify location of SLA.
+  --with-cfitsio=DIR      Specify location of CFITSIO.
+  --with-fftw3=DIR        Specify location of FFTW version 3.
+  --with-gsl=DIR          Specify location of GSL.
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CXXCPP      C++ preprocessor
+  F77         Fortran 77 compiler command
+  FFLAGS      Fortran 77 compiler flags
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+           test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.57.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+        ac_must_keep_next=false # Got value, back to normal.
+      else
+        case $ac_arg in
+          *=* | --config-cache | -C | -disable-* | --disable-* \
+          | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+          | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+          | -with-* | --with-* | -without-* | --without-* | --x)
+            case "$ac_configure_args0 " in
+              "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+            esac
+            ;;
+          -* ) ac_must_keep_next=true ;;
+        esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+        "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+    	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=$`echo $ac_var`
+        echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core core.* *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+               sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+        { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+        { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+        { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+        ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          ac_config_headers="$ac_config_headers src/config.h"
+
+am__api_version="1.8"
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+        if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+          if test $ac_prog = install &&
+            grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # AIX install.  It has an incompatible calling convention.
+            :
+          elif test $ac_prog = install &&
+            grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # program-specific install script used by HP pwplus--don't use.
+            :
+          else
+            ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+            break 3
+          fi
+        fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$*" != "X $srcdir/configure conftest.file" \
+      && test "$*" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      { { echo "$as_me:$LINENO: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" >&5
+echo "$as_me: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" >&2;}
+   { (exit 1); exit 1; }; }
+   fi
+
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+test "$program_prefix" != NONE &&
+  program_transform_name="s,^,$program_prefix,;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s,\$,$program_suffix,;$program_transform_name"
+# Double any \ or $.  echo might interpret backslashes.
+# By default was `s,x,x', remove it if useless.
+cat <<\_ACEOF >conftest.sed
+s/[\\$]/&&/g;s/;s,x,x,$//
+_ACEOF
+program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
+rm conftest.sed
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+  # Keeping the `.' argument allows $(mkdir_p) to be used without
+  # argument.  Indeed, we sometimes output rules like
+  #   $(mkdir_p) $(somedir)
+  # where $(somedir) is conditionally defined.
+  # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more
+  # expensive solution, as it forces Make to start a sub-shell.)
+  mkdir_p='mkdir -p -- .'
+else
+  # On NextStep and OpenStep, the `mkdir' command does not
+  # recognize any option.  It will interpret all options as
+  # directories to create, and then abort because `.' already
+  # exists.
+  for d in ./-p ./--version;
+  do
+    test -d $d && rmdir $d
+  done
+  # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+  if test -f "$ac_aux_dir/mkinstalldirs"; then
+    mkdir_p='$(mkinstalldirs)'
+  else
+    mkdir_p='$(install_sh) -d'
+  fi
+fi
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$AWK" && break
+done
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+	@echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+   test -f $srcdir/config.status; then
+  { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE=psModule
+ VERSION=0.1
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  STRIP=$ac_ct_STRIP
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output" >&5
+echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+        ;;
+    conftest.$ac_ext )
+        # This is the source file.
+        ;;
+    [ab].out )
+        # We found the default executable, but exeext='' is most
+        # certainly right.
+        break;;
+    *.* )
+        ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+        # FIXME: I believe we export ac_cv_exeext for Libtool,
+        # but it would be cool to find out if it's true.  Does anybody
+        # maintain Libtool? --akim.
+        export ac_cv_exeext
+        break;;
+    * )
+        break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+          export ac_cv_exeext
+          break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX 10.20 and later	-Ae
+# HP-UX older versions	-Aa -D_HPUX_SOURCE
+# SVR4			-Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   ''\
+   '#include <stdlib.h>' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+          ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+   am__include=include
+   am__quote=
+   _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+      am__include=.include
+      am__quote="\""
+      _am_result=BSD
+   fi
+fi
+
+
+echo "$as_me:$LINENO: result: $_am_result" >&5
+echo "${ECHO_T}$_am_result" >&6
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+  enableval="$enable_dependency_tracking"
+
+fi;
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+
+
+if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+
+
+depcc="$CC"   am_compiler_list=
+
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    case $depmode in
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    none) break ;;
+    esac
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.
+    if depmode=$depmode \
+       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored.
+      if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+
+
+if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+
+
+
+CFLAGS="${CFLAGS=} -g2 -Wall -std=c99 -D_GNU_SOURCE"
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+        if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+          if test $ac_prog = install &&
+            grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # AIX install.  It has an incompatible calling convention.
+            :
+          elif test $ac_prog = install &&
+            grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # program-specific install script used by HP pwplus--don't use.
+            :
+          else
+            ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+            break 3
+          fi
+        fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_shared=yes
+fi;
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+  enableval="$enable_static"
+  p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_static=yes
+fi;
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+  enableval="$enable_fast_install"
+  p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_fast_install=yes
+fi;
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+  ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+  ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking for a sed that does not truncate output" >&5
+echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6
+if test "${lt_cv_path_SED+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && break
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+SED=$lt_cv_path_SED
+
+fi
+
+echo "$as_me:$LINENO: result: $SED" >&5
+echo "${ECHO_T}$SED" >&6
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval="$with_gnu_ld"
+  test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi;
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  echo "$as_me:$LINENO: checking for ld used by $CC" >&5
+echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
+else
+  echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
+fi
+if test "${lt_cv_path_LD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+   { (exit 1); exit 1; }; }
+echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+if test "${lt_cv_prog_gnu_ld+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
+echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6
+if test "${lt_cv_ld_reload_flag+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
+echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+
+echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
+echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6
+if test "${lt_cv_path_NM+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    tmp_nm="$ac_dir/${ac_tool_prefix}nm"
+    if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      # Tru64's nm complains that /dev/null is an invalid object file
+      case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+      */dev/null* | *'Invalid file or object type'*)
+	lt_cv_path_NM="$tmp_nm -B"
+	break
+        ;;
+      *)
+	case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	*/dev/null*)
+	  lt_cv_path_NM="$tmp_nm -p"
+	  break
+	  ;;
+	*)
+	  lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	  continue # so that we can try to find one that supports BSD flags
+	  ;;
+	esac
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+  test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi
+fi
+echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5
+echo "${ECHO_T}$lt_cv_path_NM" >&6
+NM="$lt_cv_path_NM"
+
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5
+echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6
+if test "${lt_cv_deplibs_check_method+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi4*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump'.
+  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | kfreebsd*-gnu)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case "$host_cpu" in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  case $host_cpu in
+  alpha*|hppa*|i*86|ia64*|m68*|mips*|powerpc*|sparc*|s390*|sh*|x86_64*)
+    lt_cv_deplibs_check_method=pass_all ;;
+  *)
+    # glibc up to 2.1.1 does not perform some relocations on ARM
+    # this will be overridden with pass_all, but let us keep it just in case
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;;
+  esac
+  lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+nto-qnx*)
+  lt_cv_deplibs_check_method=unknown
+  ;;
+
+openbsd*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+  else
+    lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sco3.2v5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
+echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+  enableval="$enable_libtool_lock"
+
+fi;
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *ELF-32*)
+      HPUX_IA64_MODE="32"
+      ;;
+    *ELF-64*)
+      HPUX_IA64_MODE="64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line 3629 "configure"' > conftest.$ac_ext
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+   if test "$lt_cv_prog_gnu_ld" = yes; then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -melf32bsmip"
+      ;;
+    *N32*)
+      LD="${LD-ld} -melf32bmipn32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -melf64bmip"
+      ;;
+    esac
+   else
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+   fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_i386"
+          ;;
+        ppc64-*linux*|powerpc64-*linux*)
+          LD="${LD-ld} -m elf32ppclinux"
+          ;;
+        s390x-*linux*)
+          LD="${LD-ld} -m elf_s390"
+          ;;
+        sparc64-*linux*)
+          LD="${LD-ld} -m elf32_sparc"
+          ;;
+      esac
+      ;;
+    *64-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        ppc*-*linux*|powerpc*-*linux*)
+          LD="${LD-ld} -m elf64ppc"
+          ;;
+        s390*-*linux*)
+          LD="${LD-ld} -m elf64_s390"
+          ;;
+        sparc*-*linux*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
+echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6
+if test "${lt_cv_cc_needs_belf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+     cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  lt_cv_cc_needs_belf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+lt_cv_cc_needs_belf=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+     ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
+echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+esac
+
+need_locks="$enable_libtool_lock"
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                   (('a' <= (c) && (c) <= 'i') \
+                     || ('j' <= (c) && (c) <= 'r') \
+                     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+        || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+for ac_header in dlfcn.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CXX" && break
+done
+test -n "$ac_ct_CXX" || ac_ct_CXX="g++"
+
+  CXX=$ac_ct_CXX
+fi
+
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C++ compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6
+GXX=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cxx_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cxx_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cxx_g=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+for ac_declaration in \
+   ''\
+   '#include <stdlib.h>' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+depcc="$CXX"  am_compiler_list=
+
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CXX_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    case $depmode in
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    none) break ;;
+    esac
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.
+    if depmode=$depmode \
+       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored.
+      if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
+        am_cv_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CXX_dependencies_compiler_type" >&6
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+
+
+if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5
+echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6
+if test -z "$CXXCPP"; then
+  if test "${ac_cv_prog_CXXCPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+echo "$as_me:$LINENO: result: $CXXCPP" >&5
+echo "${ECHO_T}$CXXCPP" >&6
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_cxx_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in g77 f77 xlf frt pgf77 fl32 af77 fort77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 lf95 g95
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$F77"; then
+  ac_cv_prog_F77="$F77" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_F77="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+F77=$ac_cv_prog_F77
+if test -n "$F77"; then
+  echo "$as_me:$LINENO: result: $F77" >&5
+echo "${ECHO_T}$F77" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$F77" && break
+  done
+fi
+if test -z "$F77"; then
+  ac_ct_F77=$F77
+  for ac_prog in g77 f77 xlf frt pgf77 fl32 af77 fort77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 lf95 g95
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_F77"; then
+  ac_cv_prog_ac_ct_F77="$ac_ct_F77" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_F77="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_F77=$ac_cv_prog_ac_ct_F77
+if test -n "$ac_ct_F77"; then
+  echo "$as_me:$LINENO: result: $ac_ct_F77" >&5
+echo "${ECHO_T}$ac_ct_F77" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_F77" && break
+done
+
+  F77=$ac_ct_F77
+fi
+
+
+# Provide some information about the compiler.
+echo "$as_me:5128:" \
+     "checking for Fortran 77 compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+# If we don't use `.F' as extension, the preprocessor is not run on the
+# input file.
+ac_save_ext=$ac_ext
+ac_ext=F
+echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6
+if test "${ac_cv_f77_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+      program main
+#ifndef __GNUC__
+       choke me
+#endif
+
+      end
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_cv_f77_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6
+ac_ext=$ac_save_ext
+G77=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_FFLAGS=${FFLAGS+set}
+ac_save_FFLAGS=$FFLAGS
+FFLAGS=
+echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5
+echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_f77_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  FFLAGS=-g
+cat >conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_f77_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_f77_g=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5
+echo "${ECHO_T}$ac_cv_prog_f77_g" >&6
+if test "$ac_test_FFLAGS" = set; then
+  FFLAGS=$ac_save_FFLAGS
+elif test $ac_cv_prog_f77_g = yes; then
+  if test "$G77" = yes; then
+    FFLAGS="-g -O2"
+  else
+    FFLAGS="-g"
+  fi
+else
+  if test "$G77" = yes; then
+    FFLAGS="-O2"
+  else
+    FFLAGS=
+  fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+
+# find the maximum length of command line arguments
+echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5
+echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6
+if test "${lt_cv_sys_max_cmd_len+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+    i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+ *)
+    # If test is not a shell built-in, we'll probably end up computing a
+    # maximum length that is only half of the actual maximum length, but
+    # we can't tell.
+    while (test "X"`$CONFIG_SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \
+	       = "XX$teststring") >/dev/null 2>&1 &&
+	    new_result=`expr "X$teststring" : ".*" 2>&1` &&
+	    lt_cv_sys_max_cmd_len=$new_result &&
+	    test $i != 17 # 1/2 MB should be enough
+    do
+      i=`expr $i + 1`
+      teststring=$teststring$teststring
+    done
+    teststring=
+    # Add a significant safety factor because C++ compilers can tack on massive
+    # amounts of additional arguments before passing them to the linker.
+    # It appears as though 1/2 is a usable value.
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    ;;
+  esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+  echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5
+echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6
+else
+  echo "$as_me:$LINENO: result: none" >&5
+echo "${ECHO_T}none" >&6
+fi
+
+
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5
+echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6
+if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw* | pw32*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  if test "$host_cpu" = ia64; then
+    symcode='[ABCDEGRST]'
+  fi
+  lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+  lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  ;;
+irix* | nonstopux*)
+  symcode='[BCDEGRST]'
+  ;;
+osf*)
+  symcode='[BCDEGQRST]'
+  ;;
+solaris* | sysv5*)
+  symcode='[BDRT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Write the raw and C identifiers.
+  lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ 	]\($symcode$symcode*\)[ 	][ 	]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5
+  (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if grep ' nm_test_var$' "$nlist" >/dev/null; then
+	if grep ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext'
+
+	  cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext
+	  cat <<\EOF >> conftest.$ac_ext
+  {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_save_LIBS="$LIBS"
+	  lt_save_CFLAGS="$CFLAGS"
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+	  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS="$lt_save_LIBS"
+	  CFLAGS="$lt_save_CFLAGS"
+	else
+	  echo "cannot find nm_test_func in $nlist" >&5
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.$ac_ext >&5
+  fi
+  rm -f conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  echo "$as_me:$LINENO: result: failed" >&5
+echo "${ECHO_T}failed" >&6
+else
+  echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+fi
+
+echo "$as_me:$LINENO: checking for objdir" >&5
+echo $ECHO_N "checking for objdir... $ECHO_C" >&6
+if test "${lt_cv_objdir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5
+echo "${ECHO_T}$lt_cv_objdir" >&6
+objdir=$lt_cv_objdir
+
+
+
+
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="${ac_tool_prefix}ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+  ac_ct_AR=$AR
+  # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_AR" && ac_cv_prog_ac_ct_AR="false"
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
+echo "${ECHO_T}$ac_ct_AR" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  AR=$ac_ct_AR
+else
+  AR="$ac_cv_prog_AR"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  STRIP=$ac_ct_STRIP
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$SED" && SED=sed
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+    ;;
+  *)
+    old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
+echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    echo "$as_me:$LINENO: checking for file" >&5
+echo $ECHO_N "checking for file... $ECHO_C" >&6
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+enable_dlopen=no
+enable_win32_dll=no
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+  enableval="$enable_libtool_lock"
+
+fi;
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+
+# Check whether --with-pic or --without-pic was given.
+if test "${with_pic+set}" = set; then
+  withval="$with_pic"
+  pic_mode="$withval"
+else
+  pic_mode=default
+fi;
+test -z "$pic_mode" && pic_mode=default
+
+# Use C for the default configuration in the libtool script
+tagname=
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}\n'
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+#
+# Check for any special shared library compilation flags.
+#
+lt_prog_cc_shlib=
+if test "$GCC" = no; then
+  case $host_os in
+  sco3.2v5*)
+    lt_prog_cc_shlib='-belf'
+    ;;
+  esac
+fi
+if test -n "$lt_prog_cc_shlib"; then
+  { echo "$as_me:$LINENO: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&5
+echo "$as_me: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&2;}
+  if echo "$old_CC $old_CFLAGS " | grep "[ 	]$lt_prog_cc_shlib[ 	]" >/dev/null; then :
+  else
+    { echo "$as_me:$LINENO: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&5
+echo "$as_me: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&2;}
+    lt_cv_prog_cc_can_build_shared=no
+  fi
+fi
+
+
+#
+# Check to make sure the static flag actually works.
+#
+echo "$as_me:$LINENO: checking if $compiler static flag $lt_prog_compiler_static works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_prog_compiler_static works... $ECHO_C" >&6
+if test "${lt_prog_compiler_static_works+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_static_works=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_prog_compiler_static"
+   printf "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+     else
+       lt_prog_compiler_static_works=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works" >&6
+
+if test x"$lt_prog_compiler_static_works" = xyes; then
+    :
+else
+    lt_prog_compiler_static=
+fi
+
+
+
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  lt_prog_compiler_no_builtin_flag=' -fno-builtin'
+
+
+echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:6140: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:6144: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test ! -s conftest.err; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl='-Wl,'
+    lt_prog_compiler_static='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='-fPIC'
+	;;
+      esac
+      ;;
+
+    *)
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      else
+	lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    linux*)
+      case $CC in
+      icc* | ecc*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-KPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    sco3.2v5*)
+      lt_prog_compiler_pic='-Kpic'
+      lt_prog_compiler_static='-dn'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl='-Qoption ld '
+      lt_prog_compiler_pic='-PIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_prog_compiler_pic='-Kconform_pic'
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic='-pic'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic" >&6
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+
+echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6
+if test "${lt_prog_compiler_pic_works+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_pic_works=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:6373: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:6377: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test ! -s conftest.err; then
+       lt_prog_compiler_pic_works=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6
+
+if test x"$lt_prog_compiler_pic_works" = xyes; then
+    case $lt_prog_compiler_pic in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+     esac
+else
+    lt_prog_compiler_pic=
+     lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+case "$host_os" in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic=
+    ;;
+  *)
+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+    ;;
+esac
+
+echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:6433: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:6437: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test ! -s out/conftest.err; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w .
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+
+  runpath_var=
+  allow_undefined_flag=
+  enable_shared_with_static_runtimes=no
+  archive_cmds=
+  archive_expsym_cmds=
+  old_archive_From_new_cmds=
+  old_archive_from_expsyms_cmds=
+  export_dynamic_flag_spec=
+  whole_archive_flag_spec=
+  thread_safe_flag_spec=
+  hardcode_libdir_flag_spec=
+  hardcode_libdir_flag_spec_ld=
+  hardcode_libdir_separator=
+  hardcode_direct=no
+  hardcode_minus_L=no
+  hardcode_shlibpath_var=unsupported
+  link_all_deplibs=unknown
+  hardcode_automatic=no
+  module_cmds=
+  module_expsym_cmds=
+  always_export_symbols=no
+  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  ld_shlibs=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	ld_shlibs=no
+	cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+
+      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      ld_shlibs=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag=unsupported
+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      allow_undefined_flag=unsupported
+      always_export_symbols=no
+      enable_shared_with_static_runtimes=yes
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000  ${wl}--out-implib,$lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris* | sysv5*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+	ld_shlibs=no
+	cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    sunos4*)
+      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+  linux*)
+    if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_cmds="$tmp_archive_cmds"
+      supports_anon_versioning=no
+      case `$LD -v 2>/dev/null` in
+        *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+        *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+        *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+        *\ 2.11.*) ;; # other 2.11 versions
+        *) supports_anon_versioning=yes ;;
+      esac
+      if test $supports_anon_versioning = yes; then
+        archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~
+cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+$echo "local: *; };" >> $output_objdir/$libname.ver~
+        $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+      else
+        archive_expsym_cmds="$tmp_archive_cmds"
+      fi
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs" = yes; then
+      runpath_var=LD_RUN_PATH
+      hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+      export_dynamic_flag_spec='${wl}--export-dynamic'
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+ 	whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+  	whole_archive_flag_spec=
+      fi
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag=unsupported
+      always_export_symbols=yes
+      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test "$GCC" = yes && test -z "$link_static_flag"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+	  for ld_flag in $LDFLAGS; do
+  	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+  	    aix_use_runtimelinking=yes
+  	    break
+  	  fi
+	  done
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds=''
+      hardcode_direct=yes
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.012|aix4.012.*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" && \
+  	   strings "$collect2name" | grep resolve_lib_name >/dev/null
+	  then
+  	  # We have reworked collect2
+  	  hardcode_direct=yes
+	  else
+  	  # We have old collect2
+  	  hardcode_direct=unsupported
+  	  # It fails to find uninstalled libraries when the uninstalled
+  	  # path is not listed in the libpath.  Setting hardcode_minus_L
+  	  # to unsupported forces relinking
+  	  hardcode_minus_L=yes
+  	  hardcode_libdir_flag_spec='-L$libdir'
+  	  hardcode_libdir_separator=
+	  fi
+	esac
+	shared_flag='-shared'
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+  	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+  	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+  	if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+  	fi
+	fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+       hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+	archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag="-z nodefs"
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an empty executable.
+	 cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag=' ${wl}-bernotok'
+	  allow_undefined_flag=' ${wl}-berok'
+	  # -bexpall does not export symbols beginning with underscore (_)
+	  always_export_symbols=yes
+	  # Exported symbols can be pulled into shared objects from archives
+	  whole_archive_flag_spec=' '
+	  archive_cmds_need_lc=yes
+	  # This is similar to how AIX traditionally builds it's shared libraries.
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      # see comment about different semantics on the GNU ld section
+      ld_shlibs=no
+      ;;
+
+    bsdi4*)
+      export_dynamic_flag_spec=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec=' '
+      allow_undefined_flag=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_From_new_cmds='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes=yes
+      ;;
+
+    darwin* | rhapsody*)
+    if test "$GXX" = yes ; then
+      archive_cmds_need_lc=no
+      case "$host_os" in
+      rhapsody* | darwin1.[012])
+	allow_undefined_flag='-undefined suppress'
+	;;
+      *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+      	allow_undefined_flag='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[012])
+            allow_undefined_flag='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            allow_undefined_flag='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+	;;
+      esac
+    	lt_int_apple_cc_single_mod=no
+    	output_verbose_link_cmd='echo'
+    	if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
+    	  lt_int_apple_cc_single_mod=yes
+    	fi
+    	if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+    	  archive_cmds='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+    	else
+        archive_cmds='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      fi
+      module_cmds='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+        if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+          archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        else
+          archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        fi
+          module_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      hardcode_direct=no
+      hardcode_automatic=yes
+      hardcode_shlibpath_var=unsupported
+      whole_archive_flag_spec='-all_load $convenience'
+      link_all_deplibs=yes
+    else
+      ld_shlibs=no
+    fi
+      ;;
+
+    dgux*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu)
+      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      export_dynamic_flag_spec='${wl}-E'
+      ;;
+
+    hpux10* | hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case "$host_cpu" in
+	hppa*64*|ia64*)
+	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case "$host_cpu" in
+	hppa*64*|ia64*)
+	  archive_cmds='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  ;;
+	*)
+	  archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	case "$host_cpu" in
+	hppa*64*)
+	  hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	  hardcode_libdir_flag_spec_ld='+b $libdir'
+	  hardcode_libdir_separator=:
+	  hardcode_direct=no
+	  hardcode_shlibpath_var=no
+	  ;;
+	ia64*)
+	  hardcode_libdir_flag_spec='-L$libdir'
+	  hardcode_direct=no
+	  hardcode_shlibpath_var=no
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L=yes
+	  ;;
+	*)
+	  hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	  hardcode_libdir_separator=:
+	  hardcode_direct=yes
+	  export_dynamic_flag_spec='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec_ld='-rpath $libdir'
+      fi
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      link_all_deplibs=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    newsos6)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_shlibpath_var=no
+      ;;
+
+    openbsd*)
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec='${wl}-E'
+      else
+       case $host_os in
+	 openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	   archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	   hardcode_libdir_flag_spec='-R$libdir'
+	   ;;
+	 *)
+	   archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	   hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	   ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+	$LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      hardcode_libdir_separator=:
+      ;;
+
+    sco3.2v5*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='${wl}-Bexport'
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ;;
+
+    solaris*)
+      no_undefined_flag=' -z text'
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+	  $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+	archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+  	$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_shlibpath_var=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+	whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+      esac
+      link_all_deplibs=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds='$CC -r -o $output$reload_objs'
+	  hardcode_direct=no
+        ;;
+	motorola)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs=yes
+      fi
+      ;;
+
+    sysv4.2uw2*)
+      archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=no
+      hardcode_shlibpath_var=no
+      hardcode_runpath_var=yes
+      runpath_var=LD_RUN_PATH
+      ;;
+
+   sysv5OpenUNIX8* | sysv5UnixWare7* |  sysv5uw[78]* | unixware7*)
+      no_undefined_flag='${wl}-z ${wl}text'
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv5*)
+      no_undefined_flag=' -z text'
+      # $CC -shared without GNU ld will not create a library from C++
+      # object files and a static libstdc++, better avoid it by now
+      archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+  		$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      hardcode_libdir_flag_spec=
+      hardcode_shlibpath_var=no
+      runpath_var='LD_RUN_PATH'
+      ;;
+
+    uts4*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      ld_shlibs=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $ld_shlibs" >&5
+echo "${ECHO_T}$ld_shlibs" >&6
+test "$ld_shlibs" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag
+        allow_undefined_flag=
+        if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+        then
+	  archive_cmds_need_lc=no
+        else
+	  archive_cmds_need_lc=yes
+        fi
+        allow_undefined_flag=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5
+echo "${ECHO_T}$archive_cmds_need_lc" >&6
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.01* | freebsdelf3.01*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case "$host_cpu" in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # find out which ABI we are using
+  libsuff=
+  case "$host_cpu" in
+  x86_64*|s390x*|powerpc64*)
+    echo '#line 7747 "configure"' > conftest.$ac_ext
+    if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+      case `/usr/bin/file conftest.$ac_objext` in
+      *64-bit*)
+        libsuff=64
+        sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+        ;;
+      esac
+    fi
+    rm -rf conftest*
+    ;;
+  esac
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=yes
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test -n "$runpath_var " || \
+   test "X$hardcode_automatic"="Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action" >&5
+echo "${ECHO_T}$hardcode_action" >&6
+
+if test "$hardcode_action" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+striplib=
+old_striplib=
+echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
+echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+   darwin*)
+       if test -n "$STRIP" ; then
+         striplib="$STRIP -x"
+         echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+       ;;
+   *)
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+    ;;
+  esac
+fi
+
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+   ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+   ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+   ;;
+
+  *)
+    echo "$as_me:$LINENO: checking for shl_load" >&5
+echo $ECHO_N "checking for shl_load... $ECHO_C" >&6
+if test "${ac_cv_func_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shl_load (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shl_load ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+char (*f) () = shl_load;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != shl_load;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_shl_load=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
+echo "${ECHO_T}$ac_cv_func_shl_load" >&6
+if test $ac_cv_func_shl_load = yes; then
+  lt_cv_dlopen="shl_load"
+else
+  echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shl_load ();
+int
+main ()
+{
+shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
+else
+  echo "$as_me:$LINENO: checking for dlopen" >&5
+echo $ECHO_N "checking for dlopen... $ECHO_C" >&6
+if test "${ac_cv_func_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dlopen (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+char (*f) () = dlopen;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != dlopen;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_dlopen=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
+echo "${ECHO_T}$ac_cv_func_dlopen" >&6
+if test $ac_cv_func_dlopen = yes; then
+  lt_cv_dlopen="dlopen"
+else
+  echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
+echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_svld_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_svld_dlopen=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6
+if test $ac_cv_lib_svld_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
+echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dld_link ();
+int
+main ()
+{
+dld_link ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_dld_link=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_dld_link=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6
+if test $ac_cv_lib_dld_dld_link = yes; then
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
+echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 8532 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}
+EOF
+  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self" >&6
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      LDFLAGS="$LDFLAGS $link_static_flag"
+      echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
+echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 8630 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}
+EOF
+  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+# Report which librarie types wil actually be built
+echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
+echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $can_build_shared" >&5
+echo "${ECHO_T}$can_build_shared" >&6
+
+echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
+echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4* | aix5*)
+  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+    test "$enable_shared" = yes && enable_static=no
+  fi
+  ;;
+  darwin* | rhapsody*)
+  if test "$GCC" = yes; then
+    archive_cmds_need_lc=no
+    case "$host_os" in
+    rhapsody* | darwin1.[012])
+      allow_undefined_flag='-undefined suppress'
+      ;;
+    *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+      	allow_undefined_flag='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[012])
+            allow_undefined_flag='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            allow_undefined_flag='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+      ;;
+    esac
+    output_verbose_link_cmd='echo'
+    archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring'
+    module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+    # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+    archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag  -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    module_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    hardcode_direct=no
+    hardcode_automatic=yes
+    hardcode_shlibpath_var=unsupported
+    whole_archive_flag_spec='-all_load $convenience'
+    link_all_deplibs=yes
+  else
+    ld_shlibs=no
+  fi
+    ;;
+esac
+echo "$as_me:$LINENO: result: $enable_shared" >&5
+echo "${ECHO_T}$enable_shared" >&6
+
+echo "$as_me:$LINENO: checking whether to build static libraries" >&5
+echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+echo "$as_me:$LINENO: result: $enable_static" >&5
+echo "${ECHO_T}$enable_static" >&6
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler \
+    CC \
+    LD \
+    lt_prog_compiler_wl \
+    lt_prog_compiler_pic \
+    lt_prog_compiler_static \
+    lt_prog_compiler_no_builtin_flag \
+    export_dynamic_flag_spec \
+    thread_safe_flag_spec \
+    whole_archive_flag_spec \
+    enable_shared_with_static_runtimes \
+    old_archive_cmds \
+    old_archive_from_new_cmds \
+    predep_objects \
+    postdep_objects \
+    predeps \
+    postdeps \
+    compiler_lib_search_path \
+    archive_cmds \
+    archive_expsym_cmds \
+    postinstall_cmds \
+    postuninstall_cmds \
+    old_archive_from_expsyms_cmds \
+    allow_undefined_flag \
+    no_undefined_flag \
+    export_symbols_cmds \
+    hardcode_libdir_flag_spec \
+    hardcode_libdir_flag_spec_ld \
+    hardcode_libdir_separator \
+    hardcode_automatic \
+    module_cmds \
+    module_expsym_cmds \
+    lt_cv_prog_compiler_c_o \
+    exclude_expsyms \
+    include_expsyms; do
+
+    case $var in
+    old_archive_cmds | \
+    old_archive_from_new_cmds | \
+    archive_cmds | \
+    archive_expsym_cmds | \
+    module_cmds | \
+    module_expsym_cmds | \
+    old_archive_from_expsyms_cmds | \
+    export_symbols_cmds | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="${ofile}T"
+  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+  $rm -f "$cfgfile"
+  { echo "$as_me:$LINENO: creating $ofile" >&5
+echo "$as_me: creating $ofile" >&6;}
+
+  cat <<__EOF__ >> "$cfgfile"
+#! $SHELL
+
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+#
+# This file is part of GNU Libtool:
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="$SED -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+# The names of the tagged configurations supported by this script.
+available_tags=
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# A language-specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# ### END LIBTOOL CONFIG
+
+__EOF__
+
+
+  case $host_os in
+  aix3*)
+    cat <<\EOF >> "$cfgfile"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" || \
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+
+# Check whether --with-tags or --without-tags was given.
+if test "${with_tags+set}" = set; then
+  withval="$with_tags"
+  tagnames="$withval"
+fi;
+
+if test -f "$ltmain" && test -n "$tagnames"; then
+  if test ! -f "${ofile}"; then
+    { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5
+echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;}
+  fi
+
+  if test -z "$LTCC"; then
+    eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
+    if test -z "$LTCC"; then
+      { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5
+echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;}
+    else
+      { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5
+echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;}
+    fi
+  fi
+
+  # Extract list of available tagged configurations in $ofile.
+  # Note that this assumes the entire list is on one line.
+  available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'`
+
+  lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+  for tagname in $tagnames; do
+    IFS="$lt_save_ifs"
+    # Check whether tagname contains only valid characters
+    case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in
+    "") ;;
+    *)  { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5
+echo "$as_me: error: invalid tag name: $tagname" >&2;}
+   { (exit 1); exit 1; }; }
+	;;
+    esac
+
+    if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null
+    then
+      { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5
+echo "$as_me: error: tag name \"$tagname\" already exists" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+
+    # Update the list of available tags.
+    if test -n "$tagname"; then
+      echo appending configuration tag \"$tagname\" to $ofile
+
+      case $tagname in
+      CXX)
+	if test -n "$CXX" && test "X$CXX" != "Xno"; then
+	  ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_flag_spec_ld_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_automatic_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+# Source file extension for C++ test sources.
+ac_ext=cc
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(int, char *) { return(0); }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_LD=$LD
+lt_save_GCC=$GCC
+GCC=$GXX
+lt_save_with_gnu_ld=$with_gnu_ld
+lt_save_path_LD=$lt_cv_path_LD
+if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+  lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+else
+  unset lt_cv_prog_gnu_ld
+fi
+if test -n "${lt_cv_path_LDCXX+set}"; then
+  lt_cv_path_LD=$lt_cv_path_LDCXX
+else
+  unset lt_cv_path_LD
+fi
+test -z "${LDCXX+set}" || LD=$LDCXX
+CC=${CXX-"c++"}
+compiler=$CC
+compiler_CXX=$CC
+cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'`
+
+# We don't want -fno-exception wen compiling C++ code, so set the
+# no_builtin_flag separately
+if test "$GXX" = yes; then
+  lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+else
+  lt_prog_compiler_no_builtin_flag_CXX=
+fi
+
+if test "$GXX" = yes; then
+  # Set up default GNU C++ configuration
+
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval="$with_gnu_ld"
+  test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi;
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  echo "$as_me:$LINENO: checking for ld used by $CC" >&5
+echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
+else
+  echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
+fi
+if test "${lt_cv_path_LD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+   { (exit 1); exit 1; }; }
+echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+if test "${lt_cv_prog_gnu_ld+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+  # Check if GNU C++ uses GNU ld as the underlying linker, since the
+  # archiving commands below assume that GNU ld is being used.
+  if test "$with_gnu_ld" = yes; then
+    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+    #     investigate it a little bit more. (MM)
+    wlarc='${wl}'
+
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if eval "`$CC -print-prog-name=ld` --help 2>&1" | \
+	grep 'no-whole-archive' > /dev/null; then
+      whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      whole_archive_flag_spec_CXX=
+    fi
+  else
+    with_gnu_ld=no
+    wlarc=
+
+    # A generic and very simple default shared library creation
+    # command for GNU C++ for the case where it uses the native
+    # linker, instead of GNU ld.  If possible, this setting should
+    # overridden to take advantage of the native linker features on
+    # the platform it is being used on.
+    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+  fi
+
+  # Commands to make compiler produce verbose output that lists
+  # what "hidden" libraries, object files and flags are used when
+  # linking a shared library.
+  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+else
+  GXX=no
+  with_gnu_ld=no
+  wlarc=
+fi
+
+# PORTME: fill in a description of your system's C++ link characteristics
+echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+ld_shlibs_CXX=yes
+case $host_os in
+  aix3*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  aix4* | aix5*)
+    if test "$host_cpu" = ia64; then
+      # On IA64, the linker does run time linking by default, so we don't
+      # have to do anything special.
+      aix_use_runtimelinking=no
+      exp_sym_flag='-Bexport'
+      no_entry_flag=""
+    else
+      aix_use_runtimelinking=no
+
+      # Test if we are trying to use run time linking or normal
+      # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+      # need to do runtime linking.
+      case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+	for ld_flag in $LDFLAGS; do
+	  case $ld_flag in
+	  *-brtl*)
+	    aix_use_runtimelinking=yes
+	    break
+	    ;;
+	  esac
+	done
+      esac
+
+      exp_sym_flag='-bexport'
+      no_entry_flag='-bnoentry'
+    fi
+
+    # When large executables or shared objects are built, AIX ld can
+    # have problems creating the table of contents.  If linking a library
+    # or program results in "error TOC overflow" add -mminimal-toc to
+    # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+    # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+    archive_cmds_CXX=''
+    hardcode_direct_CXX=yes
+    hardcode_libdir_separator_CXX=':'
+    link_all_deplibs_CXX=yes
+
+    if test "$GXX" = yes; then
+      case $host_os in aix4.012|aix4.012.*)
+      # We only want to do this on AIX 4.2 and lower, the check
+      # below for broken collect2 doesn't work under 4.3+
+	collect2name=`${CC} -print-prog-name=collect2`
+	if test -f "$collect2name" && \
+	   strings "$collect2name" | grep resolve_lib_name >/dev/null
+	then
+	  # We have reworked collect2
+	  hardcode_direct_CXX=yes
+	else
+	  # We have old collect2
+	  hardcode_direct_CXX=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  hardcode_minus_L_CXX=yes
+	  hardcode_libdir_flag_spec_CXX='-L$libdir'
+	  hardcode_libdir_separator_CXX=
+	fi
+      esac
+      shared_flag='-shared'
+    else
+      # not using gcc
+      if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	shared_flag='-G'
+      else
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag='${wl}-G'
+	else
+	  shared_flag='${wl}-bM:SRE'
+	fi
+      fi
+    fi
+
+    # It seems that -bexpall does not export symbols beginning with
+    # underscore (_), so it is better to generate a list of symbols to export.
+    always_export_symbols_CXX=yes
+    if test "$aix_use_runtimelinking" = yes; then
+      # Warning - without using the other runtime loading flags (-brtl),
+      # -berok will link without error, but may produce a broken library.
+      allow_undefined_flag_CXX='-berok'
+      # Determine the default libpath from the value encoded in an empty executable.
+      cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+      hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+      archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+     else
+      if test "$host_cpu" = ia64; then
+	hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+	allow_undefined_flag_CXX="-z nodefs"
+	archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+      else
+	# Determine the default libpath from the value encoded in an empty executable.
+	cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+	hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+	# Warning - without using the other run time loading flags,
+	# -berok will link without error, but may produce a broken library.
+	no_undefined_flag_CXX=' ${wl}-bernotok'
+	allow_undefined_flag_CXX=' ${wl}-berok'
+	# -bexpall does not export symbols beginning with underscore (_)
+	always_export_symbols_CXX=yes
+	# Exported symbols can be pulled into shared objects from archives
+	whole_archive_flag_spec_CXX=' '
+	archive_cmds_need_lc_CXX=yes
+	# This is similar to how AIX traditionally builds it's shared libraries.
+	archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+      fi
+    fi
+    ;;
+  chorus*)
+    case $cc_basename in
+      *)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+    esac
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+    # as there is no search path for DLLs.
+    hardcode_libdir_flag_spec_CXX='-L$libdir'
+    allow_undefined_flag_CXX=unsupported
+    always_export_symbols_CXX=no
+    enable_shared_with_static_runtimes_CXX=yes
+
+    if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+      archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+      # If the export-symbols file already is a .def file (1st line
+      # is EXPORTS), use it as is; otherwise, prepend...
+      archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	cp $export_symbols $output_objdir/$soname.def;
+      else
+	echo EXPORTS > $output_objdir/$soname.def;
+	cat $export_symbols >> $output_objdir/$soname.def;
+      fi~
+      $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+    else
+      ld_shlibs_CXX=no
+    fi
+  ;;
+
+  darwin* | rhapsody*)
+  if test "$GXX" = yes; then
+    archive_cmds_need_lc_CXX=no
+    case "$host_os" in
+    rhapsody* | darwin1.[012])
+      allow_undefined_flag_CXX='-undefined suppress'
+      ;;
+    *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+      	allow_undefined_flag_CXX='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[012])
+            allow_undefined_flag_CXX='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            allow_undefined_flag_CXX='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+      ;;
+    esac
+    lt_int_apple_cc_single_mod=no
+    output_verbose_link_cmd='echo'
+    if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
+      lt_int_apple_cc_single_mod=yes
+    fi
+    if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+      archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+    else
+      archive_cmds_CXX='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+    fi
+    module_cmds_CXX='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+
+    # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+    if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+      archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    else
+      archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    hardcode_direct_CXX=no
+    hardcode_automatic_CXX=yes
+    hardcode_shlibpath_var_CXX=unsupported
+    whole_archive_flag_spec_CXX='-all_load $convenience'
+    link_all_deplibs_CXX=yes
+  else
+    ld_shlibs_CXX=no
+  fi
+    ;;
+
+  dgux*)
+    case $cc_basename in
+      ec++)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      ghcx)
+	# Green Hills C++ Compiler
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+    esac
+    ;;
+  freebsd12*)
+    # C++ shared libraries reported to be fairly broken before switch to ELF
+    ld_shlibs_CXX=no
+    ;;
+  freebsd-elf*)
+    archive_cmds_need_lc_CXX=no
+    ;;
+  freebsd* | kfreebsd*-gnu)
+    # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+    # conventions
+    ld_shlibs_CXX=yes
+    ;;
+  gnu*)
+    ;;
+  hpux9*)
+    hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+    hardcode_libdir_separator_CXX=:
+    export_dynamic_flag_spec_CXX='${wl}-E'
+    hardcode_direct_CXX=yes
+    hardcode_minus_L_CXX=yes # Not in the search PATH,
+				# but as the default
+				# location of the library.
+
+    case $cc_basename in
+    CC)
+      # FIXME: insert proper C++ library support
+      ld_shlibs_CXX=no
+      ;;
+    aCC)
+      archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      #
+      # There doesn't appear to be a way to prevent this compiler from
+      # explicitly linking system object files so we need to strip them
+      # from the output so that they don't get included in the library
+      # dependencies.
+      output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+      ;;
+    *)
+      if test "$GXX" = yes; then
+        archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+      fi
+      ;;
+    esac
+    ;;
+  hpux10*|hpux11*)
+    if test $with_gnu_ld = no; then
+      case "$host_cpu" in
+      hppa*64*)
+	hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+	hardcode_libdir_flag_spec_ld_CXX='+b $libdir'
+	hardcode_libdir_separator_CXX=:
+        ;;
+      ia64*)
+	hardcode_libdir_flag_spec_CXX='-L$libdir'
+        ;;
+      *)
+	hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator_CXX=:
+	export_dynamic_flag_spec_CXX='${wl}-E'
+        ;;
+      esac
+    fi
+    case "$host_cpu" in
+    hppa*64*)
+      hardcode_direct_CXX=no
+      hardcode_shlibpath_var_CXX=no
+      ;;
+    ia64*)
+      hardcode_direct_CXX=no
+      hardcode_shlibpath_var_CXX=no
+      hardcode_minus_L_CXX=yes # Not in the search PATH,
+					      # but as the default
+					      # location of the library.
+      ;;
+    *)
+      hardcode_direct_CXX=yes
+      hardcode_minus_L_CXX=yes # Not in the search PATH,
+					      # but as the default
+					      # location of the library.
+      ;;
+    esac
+
+    case $cc_basename in
+      CC)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      aCC)
+	case "$host_cpu" in
+	hppa*64*|ia64*)
+	  archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+	  ;;
+	*)
+	  archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	  ;;
+	esac
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	;;
+      *)
+	if test "$GXX" = yes; then
+	  if test $with_gnu_ld = no; then
+	    case "$host_cpu" in
+	    ia64*|hppa*64*)
+	      archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+	      ;;
+	    *)
+	      archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      ;;
+	    esac
+	  fi
+	else
+	  # FIXME: insert proper C++ library support
+	  ld_shlibs_CXX=no
+	fi
+	;;
+    esac
+    ;;
+  irix5* | irix6*)
+    case $cc_basename in
+      CC)
+	# SGI C++
+	archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+
+	# Archives containing C++ object files must be created using
+	# "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	# necessary to make sure instantiated templates are included
+	# in the archive.
+	old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	;;
+      *)
+	if test "$GXX" = yes; then
+	  if test "$with_gnu_ld" = no; then
+	    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+	  else
+	    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
+	  fi
+	fi
+	link_all_deplibs_CXX=yes
+	;;
+    esac
+    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator_CXX=:
+    ;;
+  linux*)
+    case $cc_basename in
+      KCC)
+	# Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	# KCC will only create a shared library if the output file
+	# ends with ".so" (or ".sl" for HP-UX), so rename the library
+	# to its proper name (with version) after linking.
+	archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+	hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir'
+	export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+	# Archives containing C++ object files must be created using
+	# "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+	;;
+      icpc)
+	# Intel C++
+	with_gnu_ld=yes
+	archive_cmds_need_lc_CXX=no
+	archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	;;
+      cxx)
+	# Compaq C++
+	archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+	runpath_var=LD_RUN_PATH
+	hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+	hardcode_libdir_separator_CXX=:
+
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	;;
+    esac
+    ;;
+  lynxos*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  m88k*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  mvs*)
+    case $cc_basename in
+      cxx)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+    esac
+    ;;
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds_CXX='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+      wlarc=
+      hardcode_libdir_flag_spec_CXX='-R$libdir'
+      hardcode_direct_CXX=yes
+      hardcode_shlibpath_var_CXX=no
+    fi
+    # Workaround some broken pre-1.5 toolchains
+    output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+    ;;
+  osf3*)
+    case $cc_basename in
+      KCC)
+	# Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	# KCC will only create a shared library if the output file
+	# ends with ".so" (or ".sl" for HP-UX), so rename the library
+	# to its proper name (with version) after linking.
+	archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	hardcode_libdir_separator_CXX=:
+
+	# Archives containing C++ object files must be created using
+	# "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+
+	;;
+      RCC)
+	# Rational C++ 2.4.1
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      cxx)
+	allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	hardcode_libdir_separator_CXX=:
+
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	;;
+      *)
+	if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	  allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	  archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+
+	  hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	  hardcode_libdir_separator_CXX=:
+
+	  # Commands to make compiler produce verbose output that lists
+	  # what "hidden" libraries, object files and flags are used when
+	  # linking a shared library.
+	  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+	else
+	  # FIXME: insert proper C++ library support
+	  ld_shlibs_CXX=no
+	fi
+	;;
+    esac
+    ;;
+  osf4* | osf5*)
+    case $cc_basename in
+      KCC)
+	# Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	# KCC will only create a shared library if the output file
+	# ends with ".so" (or ".sl" for HP-UX), so rename the library
+	# to its proper name (with version) after linking.
+	archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	hardcode_libdir_separator_CXX=:
+
+	# Archives containing C++ object files must be created using
+	# the KAI C++ compiler.
+	old_archive_cmds_CXX='$CC -o $oldlib $oldobjs'
+	;;
+      RCC)
+	# Rational C++ 2.4.1
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      cxx)
+	allow_undefined_flag_CXX=' -expect_unresolved \*'
+	archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+	archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+	  echo "-hidden">> $lib.exp~
+	  $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp  `test -n "$verstring" && echo -set_version	$verstring` -update_registry $objdir/so_locations -o $lib~
+	  $rm $lib.exp'
+
+	hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+	hardcode_libdir_separator_CXX=:
+
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+	;;
+      *)
+	if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	  allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	 archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+
+	  hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	  hardcode_libdir_separator_CXX=:
+
+	  # Commands to make compiler produce verbose output that lists
+	  # what "hidden" libraries, object files and flags are used when
+	  # linking a shared library.
+	  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+	else
+	  # FIXME: insert proper C++ library support
+	  ld_shlibs_CXX=no
+	fi
+	;;
+    esac
+    ;;
+  psos*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  sco*)
+    archive_cmds_need_lc_CXX=no
+    case $cc_basename in
+      CC)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+    esac
+    ;;
+  sunos4*)
+    case $cc_basename in
+      CC)
+	# Sun C++ 4.x
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      lcc)
+	# Lucid
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+    esac
+    ;;
+  solaris*)
+    case $cc_basename in
+      CC)
+	# Sun C++ 4.2, 5.x and Centerline C++
+	no_undefined_flag_CXX=' -zdefs'
+	archive_cmds_CXX='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+	$CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+	hardcode_libdir_flag_spec_CXX='-R$libdir'
+	hardcode_shlibpath_var_CXX=no
+	case $host_os in
+	  solaris2.0-5 | solaris2.0-5.*) ;;
+	  *)
+	    # The C++ compiler is used as linker so we must use $wl
+	    # flag to pass the commands to the underlying system
+	    # linker.
+	    # Supported since Solaris 2.6 (maybe 2.5.1?)
+	    whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	    ;;
+	esac
+	link_all_deplibs_CXX=yes
+
+	# Commands to make compiler produce verbose output that lists
+	# what "hidden" libraries, object files and flags are used when
+	# linking a shared library.
+	#
+	# There doesn't appear to be a way to prevent this compiler from
+	# explicitly linking system object files so we need to strip them
+	# from the output so that they don't get included in the library
+	# dependencies.
+	output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[LR]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+	# Archives containing C++ object files must be created using
+	# "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	# necessary to make sure instantiated templates are included
+	# in the archive.
+	old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	;;
+      gcx)
+	# Green Hills C++ Compiler
+	archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+	# The C++ compiler must be used to create the archive.
+	old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	;;
+      *)
+	# GNU C++ compiler with Solaris linker
+	if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	  no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+	  if $CC --version | grep -v '^2\.7' > /dev/null; then
+	    archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	    archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+		$CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+	  else
+	    # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	    # platform.
+	    archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	    archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+		$CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+	  fi
+
+	  hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+	fi
+	;;
+    esac
+    ;;
+  sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*)
+    archive_cmds_need_lc_CXX=no
+    ;;
+  tandem*)
+    case $cc_basename in
+      NCC)
+	# NonStop-UX NCC 3.20
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+      *)
+	# FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+    esac
+    ;;
+  vxworks*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  *)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+esac
+echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
+echo "${ECHO_T}$ld_shlibs_CXX" >&6
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+GCC_CXX="$GXX"
+LD_CXX="$LD"
+
+
+cat > conftest.$ac_ext <<EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+EOF
+
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  # The `*' in the case matches for architectures that use `case' in
+  # $output_verbose_cmd can trigger glob expansion during the loop
+  # eval without this substitution.
+  output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`"
+
+  for p in `eval $output_verbose_link_cmd`; do
+    case $p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" \
+	  || test $p = "-R"; then
+	 prev=$p
+	 continue
+       else
+	 prev=
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 case $p in
+	 -L* | -R*)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$compiler_lib_search_path_CXX"; then
+	     compiler_lib_search_path_CXX="${prev}${p}"
+	   else
+	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$postdeps_CXX"; then
+	   postdeps_CXX="${prev}${p}"
+	 else
+	   postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+	 fi
+       fi
+       ;;
+
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 if test -z "$predep_objects_CXX"; then
+	   predep_objects_CXX="$p"
+	 else
+	   predep_objects_CXX="$predep_objects_CXX $p"
+	 fi
+       else
+	 if test -z "$postdep_objects_CXX"; then
+	   postdep_objects_CXX="$p"
+	 else
+	   postdep_objects_CXX="$postdep_objects_CXX $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$rm -f confest.$objext
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+
+lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    lt_prog_compiler_wl_CXX='-Wl,'
+    lt_prog_compiler_static_CXX='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static_CXX='-Bstatic'
+      fi
+      ;;
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
+      ;;
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | os2* | pw32*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_CXX='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      lt_prog_compiler_pic_CXX=
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic_CXX=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+	;;
+      *)
+	lt_prog_compiler_pic_CXX='-fPIC'
+	;;
+      esac
+      ;;
+    *)
+      lt_prog_compiler_pic_CXX='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix4* | aix5*)
+	# All AIX code is PIC.
+	if test "$host_cpu" = ia64; then
+	  # AIX 5 now supports IA64 processor
+	  lt_prog_compiler_static_CXX='-Bstatic'
+	else
+	  lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68)
+	  # Green Hills C++ Compiler
+	  # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++)
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  ghcx)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | kfreebsd*-gnu)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
+	    if test "$host_cpu" != ia64; then
+	      lt_prog_compiler_pic_CXX='+Z'
+	    fi
+	    ;;
+	  aCC)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
+	    case "$host_cpu" in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      lt_prog_compiler_pic_CXX='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux*)
+	case $cc_basename in
+	  KCC)
+	    # KAI C++ Compiler
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    ;;
+	  icpc)
+	    # Intel C++
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  cxx)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx)
+	    lt_prog_compiler_pic_CXX='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd*)
+	;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC)
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    ;;
+	  RCC)
+	    # Rational C++ 2.4.1
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  cxx)
+	    # Digital/Compaq C++
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      sco*)
+	case $cc_basename in
+	  CC)
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    lt_prog_compiler_wl_CXX='-Qoption ld '
+	    ;;
+	  gcx)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC)
+	    # Sun C++ 4.x
+	    lt_prog_compiler_pic_CXX='-pic'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	  lcc)
+	    # Lucid
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC)
+	    # NonStop-UX NCC 3.20
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      unixware*)
+	;;
+      vxworks*)
+	;;
+      *)
+	lt_prog_compiler_can_build_shared_CXX=no
+	;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+
+echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6
+if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_pic_works_CXX=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:10789: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:10793: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test ! -s conftest.err; then
+       lt_prog_compiler_pic_works_CXX=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6
+
+if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then
+    case $lt_prog_compiler_pic_CXX in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+     esac
+else
+    lt_prog_compiler_pic_CXX=
+     lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+case "$host_os" in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_CXX=
+    ;;
+  *)
+    lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+    ;;
+esac
+
+echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:10849: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:10853: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test ! -s out/conftest.err; then
+       lt_cv_prog_compiler_c_o_CXX=yes
+     fi
+   fi
+   chmod u+w .
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+
+  export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  case $host_os in
+  aix4* | aix5*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+    else
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    export_symbols_cmds_CXX="$ltdll_cmds"
+  ;;
+  cygwin* | mingw*)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  *)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  esac
+
+echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
+echo "${ECHO_T}$ld_shlibs_CXX" >&6
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_CXX=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_CXX in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl_CXX
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+        allow_undefined_flag_CXX=
+        if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+        then
+	  archive_cmds_need_lc_CXX=no
+        else
+	  archive_cmds_need_lc_CXX=yes
+        fi
+        allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5
+echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.01* | freebsdelf3.01*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case "$host_cpu" in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # find out which ABI we are using
+  libsuff=
+  case "$host_cpu" in
+  x86_64*|s390x*|powerpc64*)
+    echo '#line 11360 "configure"' > conftest.$ac_ext
+    if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+      case `/usr/bin/file conftest.$ac_objext` in
+      *64-bit*)
+        libsuff=64
+        sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+        ;;
+      esac
+    fi
+    rm -rf conftest*
+    ;;
+  esac
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=yes
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" || \
+   test -n "$runpath_var CXX" || \
+   test "X$hardcode_automatic_CXX"="Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct_CXX" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_CXX=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_CXX=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_CXX=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5
+echo "${ECHO_T}$hardcode_action_CXX" >&6
+
+if test "$hardcode_action_CXX" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+striplib=
+old_striplib=
+echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
+echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+   darwin*)
+       if test -n "$STRIP" ; then
+         striplib="$STRIP -x"
+         echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+       ;;
+   *)
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+    ;;
+  esac
+fi
+
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+   ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+   ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+   ;;
+
+  *)
+    echo "$as_me:$LINENO: checking for shl_load" >&5
+echo $ECHO_N "checking for shl_load... $ECHO_C" >&6
+if test "${ac_cv_func_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shl_load (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shl_load ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+char (*f) () = shl_load;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != shl_load;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_shl_load=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
+echo "${ECHO_T}$ac_cv_func_shl_load" >&6
+if test $ac_cv_func_shl_load = yes; then
+  lt_cv_dlopen="shl_load"
+else
+  echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shl_load ();
+int
+main ()
+{
+shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
+else
+  echo "$as_me:$LINENO: checking for dlopen" >&5
+echo $ECHO_N "checking for dlopen... $ECHO_C" >&6
+if test "${ac_cv_func_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dlopen (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+char (*f) () = dlopen;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != dlopen;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_dlopen=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
+echo "${ECHO_T}$ac_cv_func_dlopen" >&6
+if test $ac_cv_func_dlopen = yes; then
+  lt_cv_dlopen="dlopen"
+else
+  echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
+echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_svld_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_svld_dlopen=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6
+if test $ac_cv_lib_svld_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
+echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dld_link ();
+int
+main ()
+{
+dld_link ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_dld_link=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_dld_link=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6
+if test $ac_cv_lib_dld_dld_link = yes; then
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
+echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 12145 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}
+EOF
+  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self" >&6
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      LDFLAGS="$LDFLAGS $link_static_flag"
+      echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
+echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 12243 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}
+EOF
+  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler_CXX \
+    CC_CXX \
+    LD_CXX \
+    lt_prog_compiler_wl_CXX \
+    lt_prog_compiler_pic_CXX \
+    lt_prog_compiler_static_CXX \
+    lt_prog_compiler_no_builtin_flag_CXX \
+    export_dynamic_flag_spec_CXX \
+    thread_safe_flag_spec_CXX \
+    whole_archive_flag_spec_CXX \
+    enable_shared_with_static_runtimes_CXX \
+    old_archive_cmds_CXX \
+    old_archive_from_new_cmds_CXX \
+    predep_objects_CXX \
+    postdep_objects_CXX \
+    predeps_CXX \
+    postdeps_CXX \
+    compiler_lib_search_path_CXX \
+    archive_cmds_CXX \
+    archive_expsym_cmds_CXX \
+    postinstall_cmds_CXX \
+    postuninstall_cmds_CXX \
+    old_archive_from_expsyms_cmds_CXX \
+    allow_undefined_flag_CXX \
+    no_undefined_flag_CXX \
+    export_symbols_cmds_CXX \
+    hardcode_libdir_flag_spec_CXX \
+    hardcode_libdir_flag_spec_ld_CXX \
+    hardcode_libdir_separator_CXX \
+    hardcode_automatic_CXX \
+    module_cmds_CXX \
+    module_expsym_cmds_CXX \
+    lt_cv_prog_compiler_c_o_CXX \
+    exclude_expsyms_CXX \
+    include_expsyms_CXX; do
+
+    case $var in
+    old_archive_cmds_CXX | \
+    old_archive_from_new_cmds_CXX | \
+    archive_cmds_CXX | \
+    archive_expsym_cmds_CXX | \
+    module_cmds_CXX | \
+    module_expsym_cmds_CXX | \
+    old_archive_from_expsyms_cmds_CXX | \
+    export_symbols_cmds_CXX | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="$ofile"
+
+  cat <<__EOF__ >> "$cfgfile"
+# ### BEGIN LIBTOOL TAG CONFIG: $tagname
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# A language-specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC_CXX
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds_CXX
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects_CXX
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects_CXX
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps_CXX
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic_CXX
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path_CXX"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# ### END LIBTOOL TAG CONFIG: $tagname
+
+__EOF__
+
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC=$lt_save_CC
+LDCXX=$LD
+LD=$lt_save_LD
+GCC=$lt_save_GCC
+with_gnu_ldcxx=$with_gnu_ld
+with_gnu_ld=$lt_save_with_gnu_ld
+lt_cv_path_LDCXX=$lt_cv_path_LD
+lt_cv_path_LD=$lt_save_path_LD
+lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+
+	else
+	  tagname=""
+	fi
+	;;
+
+      F77)
+	if test -n "$F77" && test "X$F77" != "Xno"; then
+
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+
+archive_cmds_need_lc_F77=no
+allow_undefined_flag_F77=
+always_export_symbols_F77=no
+archive_expsym_cmds_F77=
+export_dynamic_flag_spec_F77=
+hardcode_direct_F77=no
+hardcode_libdir_flag_spec_F77=
+hardcode_libdir_flag_spec_ld_F77=
+hardcode_libdir_separator_F77=
+hardcode_minus_L_F77=no
+hardcode_automatic_F77=no
+module_cmds_F77=
+module_expsym_cmds_F77=
+link_all_deplibs_F77=unknown
+old_archive_cmds_F77=$old_archive_cmds
+no_undefined_flag_F77=
+whole_archive_flag_spec_F77=
+enable_shared_with_static_runtimes_F77=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+objext_F77=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="      subroutine t\n      return\n      end\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="      program t\n      end\n"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${F77-"f77"}
+compiler=$CC
+compiler_F77=$CC
+cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'`
+
+echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
+echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $can_build_shared" >&5
+echo "${ECHO_T}$can_build_shared" >&6
+
+echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
+echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+aix4* | aix5*)
+  test "$enable_shared" = yes && enable_static=no
+  ;;
+esac
+echo "$as_me:$LINENO: result: $enable_shared" >&5
+echo "${ECHO_T}$enable_shared" >&6
+
+echo "$as_me:$LINENO: checking whether to build static libraries" >&5
+echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+echo "$as_me:$LINENO: result: $enable_static" >&5
+echo "${ECHO_T}$enable_static" >&6
+
+test "$ld_shlibs_F77" = no && can_build_shared=no
+
+GCC_F77="$G77"
+LD_F77="$LD"
+
+lt_prog_compiler_wl_F77=
+lt_prog_compiler_pic_F77=
+lt_prog_compiler_static_F77=
+
+echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl_F77='-Wl,'
+    lt_prog_compiler_static_F77='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static_F77='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_F77='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_F77='-fno-common'
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared_F77=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic_F77=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic_F77='-fPIC'
+	;;
+      esac
+      ;;
+
+    *)
+      lt_prog_compiler_pic_F77='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static_F77='-Bstatic'
+      else
+	lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_F77='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic_F77='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static_F77='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static_F77='-non_shared'
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    linux*)
+      case $CC in
+      icc* | ecc*)
+	lt_prog_compiler_wl_F77='-Wl,'
+	lt_prog_compiler_pic_F77='-KPIC'
+	lt_prog_compiler_static_F77='-static'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl_F77='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static_F77='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static_F77='-non_shared'
+      ;;
+
+    sco3.2v5*)
+      lt_prog_compiler_pic_F77='-Kpic'
+      lt_prog_compiler_static_F77='-dn'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl_F77='-Qoption ld '
+      lt_prog_compiler_pic_F77='-PIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_prog_compiler_pic_F77='-Kconform_pic'
+	lt_prog_compiler_static_F77='-Bstatic'
+      fi
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic_F77='-pic'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared_F77=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_F77"; then
+
+echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6
+if test "${lt_prog_compiler_pic_works_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_pic_works_F77=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_F77"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:13070: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:13074: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test ! -s conftest.err; then
+       lt_prog_compiler_pic_works_F77=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6
+
+if test x"$lt_prog_compiler_pic_works_F77" = xyes; then
+    case $lt_prog_compiler_pic_F77 in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;;
+     esac
+else
+    lt_prog_compiler_pic_F77=
+     lt_prog_compiler_can_build_shared_F77=no
+fi
+
+fi
+case "$host_os" in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_F77=
+    ;;
+  *)
+    lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77"
+    ;;
+esac
+
+echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_c_o_F77=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:13130: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:13134: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test ! -s out/conftest.err; then
+       lt_cv_prog_compiler_c_o_F77=yes
+     fi
+   fi
+   chmod u+w .
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+
+  runpath_var=
+  allow_undefined_flag_F77=
+  enable_shared_with_static_runtimes_F77=no
+  archive_cmds_F77=
+  archive_expsym_cmds_F77=
+  old_archive_From_new_cmds_F77=
+  old_archive_from_expsyms_cmds_F77=
+  export_dynamic_flag_spec_F77=
+  whole_archive_flag_spec_F77=
+  thread_safe_flag_spec_F77=
+  hardcode_libdir_flag_spec_F77=
+  hardcode_libdir_flag_spec_ld_F77=
+  hardcode_libdir_separator_F77=
+  hardcode_direct_F77=no
+  hardcode_minus_L_F77=no
+  hardcode_shlibpath_var_F77=unsupported
+  link_all_deplibs_F77=unknown
+  hardcode_automatic_F77=no
+  module_cmds_F77=
+  module_expsym_cmds_F77=
+  always_export_symbols_F77=no
+  export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms_F77=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  ld_shlibs_F77=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	ld_shlibs_F77=no
+	cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_minus_L_F77=yes
+
+      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      ld_shlibs_F77=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag_F77=unsupported
+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	ld_shlibs_F77=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      allow_undefined_flag_F77=unsupported
+      always_export_symbols_F77=no
+      enable_shared_with_static_runtimes_F77=yes
+      export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000  ${wl}--out-implib,$lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+	archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris* | sysv5*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+	ld_shlibs_F77=no
+	cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs_F77=no
+      fi
+      ;;
+
+    sunos4*)
+      archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+  linux*)
+    if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_cmds_F77="$tmp_archive_cmds"
+      supports_anon_versioning=no
+      case `$LD -v 2>/dev/null` in
+        *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+        *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+        *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+        *\ 2.11.*) ;; # other 2.11 versions
+        *) supports_anon_versioning=yes ;;
+      esac
+      if test $supports_anon_versioning = yes; then
+        archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~
+cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+$echo "local: *; };" >> $output_objdir/$libname.ver~
+        $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+      else
+        archive_expsym_cmds_F77="$tmp_archive_cmds"
+      fi
+    else
+      ld_shlibs_F77=no
+    fi
+    ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs_F77=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs_F77" = yes; then
+      runpath_var=LD_RUN_PATH
+      hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir'
+      export_dynamic_flag_spec_F77='${wl}--export-dynamic'
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+ 	whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+  	whole_archive_flag_spec_F77=
+      fi
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag_F77=unsupported
+      always_export_symbols_F77=yes
+      archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L_F77=yes
+      if test "$GCC" = yes && test -z "$link_static_flag"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct_F77=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+	  export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+	  for ld_flag in $LDFLAGS; do
+  	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+  	    aix_use_runtimelinking=yes
+  	    break
+  	  fi
+	  done
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds_F77=''
+      hardcode_direct_F77=yes
+      hardcode_libdir_separator_F77=':'
+      link_all_deplibs_F77=yes
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.012|aix4.012.*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" && \
+  	   strings "$collect2name" | grep resolve_lib_name >/dev/null
+	  then
+  	  # We have reworked collect2
+  	  hardcode_direct_F77=yes
+	  else
+  	  # We have old collect2
+  	  hardcode_direct_F77=unsupported
+  	  # It fails to find uninstalled libraries when the uninstalled
+  	  # path is not listed in the libpath.  Setting hardcode_minus_L
+  	  # to unsupported forces relinking
+  	  hardcode_minus_L_F77=yes
+  	  hardcode_libdir_flag_spec_F77='-L$libdir'
+  	  hardcode_libdir_separator_F77=
+	  fi
+	esac
+	shared_flag='-shared'
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+  	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+  	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+  	if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+  	fi
+	fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols_F77=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag_F77='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       cat >conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+       hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
+	archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag_F77="-z nodefs"
+	  archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an empty executable.
+	 cat >conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+	 hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag_F77=' ${wl}-bernotok'
+	  allow_undefined_flag_F77=' ${wl}-berok'
+	  # -bexpall does not export symbols beginning with underscore (_)
+	  always_export_symbols_F77=yes
+	  # Exported symbols can be pulled into shared objects from archives
+	  whole_archive_flag_spec_F77=' '
+	  archive_cmds_need_lc_F77=yes
+	  # This is similar to how AIX traditionally builds it's shared libraries.
+	  archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_minus_L_F77=yes
+      # see comment about different semantics on the GNU ld section
+      ld_shlibs_F77=no
+      ;;
+
+    bsdi4*)
+      export_dynamic_flag_spec_F77=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec_F77=' '
+      allow_undefined_flag_F77=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_From_new_cmds_F77='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes_F77=yes
+      ;;
+
+    darwin* | rhapsody*)
+    if test "$GXX" = yes ; then
+      archive_cmds_need_lc_F77=no
+      case "$host_os" in
+      rhapsody* | darwin1.[012])
+	allow_undefined_flag_F77='-undefined suppress'
+	;;
+      *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+      	allow_undefined_flag_F77='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[012])
+            allow_undefined_flag_F77='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            allow_undefined_flag_F77='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+	;;
+      esac
+    	lt_int_apple_cc_single_mod=no
+    	output_verbose_link_cmd='echo'
+    	if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
+    	  lt_int_apple_cc_single_mod=yes
+    	fi
+    	if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+    	  archive_cmds_F77='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+    	else
+        archive_cmds_F77='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      fi
+      module_cmds_F77='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+        if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+          archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        else
+          archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        fi
+          module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      hardcode_direct_F77=no
+      hardcode_automatic_F77=yes
+      hardcode_shlibpath_var_F77=unsupported
+      whole_archive_flag_spec_F77='-all_load $convenience'
+      link_all_deplibs_F77=yes
+    else
+      ld_shlibs_F77=no
+    fi
+      ;;
+
+    dgux*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs_F77=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_F77=yes
+      hardcode_minus_L_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu)
+      archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      hardcode_direct_F77=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L_F77=yes
+      export_dynamic_flag_spec_F77='${wl}-E'
+      ;;
+
+    hpux10* | hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case "$host_cpu" in
+	hppa*64*|ia64*)
+	  archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case "$host_cpu" in
+	hppa*64*|ia64*)
+	  archive_cmds_F77='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  ;;
+	*)
+	  archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	case "$host_cpu" in
+	hppa*64*)
+	  hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+	  hardcode_libdir_flag_spec_ld_F77='+b $libdir'
+	  hardcode_libdir_separator_F77=:
+	  hardcode_direct_F77=no
+	  hardcode_shlibpath_var_F77=no
+	  ;;
+	ia64*)
+	  hardcode_libdir_flag_spec_F77='-L$libdir'
+	  hardcode_direct_F77=no
+	  hardcode_shlibpath_var_F77=no
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L_F77=yes
+	  ;;
+	*)
+	  hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+	  hardcode_libdir_separator_F77=:
+	  hardcode_direct_F77=yes
+	  export_dynamic_flag_spec_F77='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L_F77=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec_ld_F77='-rpath $libdir'
+      fi
+      hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      link_all_deplibs_F77=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+	archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    newsos6)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_F77=yes
+      hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    openbsd*)
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_F77='${wl}-E'
+      else
+       case $host_os in
+	 openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	   archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	   hardcode_libdir_flag_spec_F77='-R$libdir'
+	   ;;
+	 *)
+	   archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	   hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+	   ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_minus_L_F77=yes
+      allow_undefined_flag_F77=unsupported
+      archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	allow_undefined_flag_F77=' -expect_unresolved \*'
+	archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      else
+	allow_undefined_flag_F77=' -expect_unresolved \*'
+	archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+	$LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec_F77='-rpath $libdir'
+      fi
+      hardcode_libdir_separator_F77=:
+      ;;
+
+    sco3.2v5*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var_F77=no
+      export_dynamic_flag_spec_F77='${wl}-Bexport'
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ;;
+
+    solaris*)
+      no_undefined_flag_F77=' -z text'
+      if test "$GCC" = yes; then
+	archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+	  $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+	archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+  	$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_shlibpath_var_F77=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+	whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;;
+      esac
+      link_all_deplibs_F77=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_direct_F77=yes
+      hardcode_minus_L_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct_F77=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds_F77='$CC -r -o $output$reload_objs'
+	  hardcode_direct_F77=no
+        ;;
+	motorola)
+	  archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var_F77=no
+      export_dynamic_flag_spec_F77='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var_F77=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs_F77=yes
+      fi
+      ;;
+
+    sysv4.2uw2*)
+      archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_F77=yes
+      hardcode_minus_L_F77=no
+      hardcode_shlibpath_var_F77=no
+      hardcode_runpath_var=yes
+      runpath_var=LD_RUN_PATH
+      ;;
+
+   sysv5OpenUNIX8* | sysv5UnixWare7* |  sysv5uw[78]* | unixware7*)
+      no_undefined_flag_F77='${wl}-z ${wl}text'
+      if test "$GCC" = yes; then
+	archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_F77='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    sysv5*)
+      no_undefined_flag_F77=' -z text'
+      # $CC -shared without GNU ld will not create a library from C++
+      # object files and a static libstdc++, better avoid it by now
+      archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+  		$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      hardcode_libdir_flag_spec_F77=
+      hardcode_shlibpath_var_F77=no
+      runpath_var='LD_RUN_PATH'
+      ;;
+
+    uts4*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    *)
+      ld_shlibs_F77=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5
+echo "${ECHO_T}$ld_shlibs_F77" >&6
+test "$ld_shlibs_F77" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_F77" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_F77=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_F77 in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl_F77
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag_F77
+        allow_undefined_flag_F77=
+        if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+        then
+	  archive_cmds_need_lc_F77=no
+        else
+	  archive_cmds_need_lc_F77=yes
+        fi
+        allow_undefined_flag_F77=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5
+echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.01* | freebsdelf3.01*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case "$host_cpu" in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # find out which ABI we are using
+  libsuff=
+  case "$host_cpu" in
+  x86_64*|s390x*|powerpc64*)
+    echo '#line 14422 "configure"' > conftest.$ac_ext
+    if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+      case `/usr/bin/file conftest.$ac_objext` in
+      *64-bit*)
+        libsuff=64
+        sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+        ;;
+      esac
+    fi
+    rm -rf conftest*
+    ;;
+  esac
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=yes
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action_F77=
+if test -n "$hardcode_libdir_flag_spec_F77" || \
+   test -n "$runpath_var F77" || \
+   test "X$hardcode_automatic_F77"="Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct_F77" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no &&
+     test "$hardcode_minus_L_F77" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_F77=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_F77=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_F77=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5
+echo "${ECHO_T}$hardcode_action_F77" >&6
+
+if test "$hardcode_action_F77" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+striplib=
+old_striplib=
+echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
+echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+   darwin*)
+       if test -n "$STRIP" ; then
+         striplib="$STRIP -x"
+         echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+       ;;
+   *)
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+    ;;
+  esac
+fi
+
+
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler_F77 \
+    CC_F77 \
+    LD_F77 \
+    lt_prog_compiler_wl_F77 \
+    lt_prog_compiler_pic_F77 \
+    lt_prog_compiler_static_F77 \
+    lt_prog_compiler_no_builtin_flag_F77 \
+    export_dynamic_flag_spec_F77 \
+    thread_safe_flag_spec_F77 \
+    whole_archive_flag_spec_F77 \
+    enable_shared_with_static_runtimes_F77 \
+    old_archive_cmds_F77 \
+    old_archive_from_new_cmds_F77 \
+    predep_objects_F77 \
+    postdep_objects_F77 \
+    predeps_F77 \
+    postdeps_F77 \
+    compiler_lib_search_path_F77 \
+    archive_cmds_F77 \
+    archive_expsym_cmds_F77 \
+    postinstall_cmds_F77 \
+    postuninstall_cmds_F77 \
+    old_archive_from_expsyms_cmds_F77 \
+    allow_undefined_flag_F77 \
+    no_undefined_flag_F77 \
+    export_symbols_cmds_F77 \
+    hardcode_libdir_flag_spec_F77 \
+    hardcode_libdir_flag_spec_ld_F77 \
+    hardcode_libdir_separator_F77 \
+    hardcode_automatic_F77 \
+    module_cmds_F77 \
+    module_expsym_cmds_F77 \
+    lt_cv_prog_compiler_c_o_F77 \
+    exclude_expsyms_F77 \
+    include_expsyms_F77; do
+
+    case $var in
+    old_archive_cmds_F77 | \
+    old_archive_from_new_cmds_F77 | \
+    archive_cmds_F77 | \
+    archive_expsym_cmds_F77 | \
+    module_cmds_F77 | \
+    module_expsym_cmds_F77 | \
+    old_archive_from_expsyms_cmds_F77 | \
+    export_symbols_cmds_F77 | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="$ofile"
+
+  cat <<__EOF__ >> "$cfgfile"
+# ### BEGIN LIBTOOL TAG CONFIG: $tagname
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_F77
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# A language-specific compiler.
+CC=$lt_compiler_F77
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC_F77
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD_F77
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_F77
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_F77
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_F77
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds_F77
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds_F77
+archive_expsym_cmds=$lt_archive_expsym_cmds_F77
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds_F77
+module_expsym_cmds=$lt_module_expsym_cmds_F77
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects_F77
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects_F77
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps_F77
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps_F77
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_F77
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_F77
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_F77
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_F77
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct_F77
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L_F77
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_F77
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic_F77
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_F77
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path_F77"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols_F77
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_F77
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_F77
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_F77
+
+# ### END LIBTOOL TAG CONFIG: $tagname
+
+__EOF__
+
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+	else
+	  tagname=""
+	fi
+	;;
+
+      GCJ)
+	if test -n "$GCJ" && test "X$GCJ" != "Xno"; then
+
+
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+objext_GCJ=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String argv) {}; }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${GCJ-"gcj"}
+compiler=$CC
+compiler_GCJ=$CC
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+archive_cmds_need_lc_GCJ=no
+
+
+lt_prog_compiler_no_builtin_flag_GCJ=
+
+if test "$GCC" = yes; then
+  lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin'
+
+
+echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:15163: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:15167: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test ! -s conftest.err; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+lt_prog_compiler_wl_GCJ=
+lt_prog_compiler_pic_GCJ=
+lt_prog_compiler_static_GCJ=
+
+echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl_GCJ='-Wl,'
+    lt_prog_compiler_static_GCJ='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static_GCJ='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_GCJ='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_GCJ='-fno-common'
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared_GCJ=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic_GCJ=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic_GCJ='-fPIC'
+	;;
+      esac
+      ;;
+
+    *)
+      lt_prog_compiler_pic_GCJ='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static_GCJ='-Bstatic'
+      else
+	lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_GCJ='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case "$host_cpu" in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic_GCJ='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static_GCJ='-non_shared'
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic_GCJ='-KPIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    linux*)
+      case $CC in
+      icc* | ecc*)
+	lt_prog_compiler_wl_GCJ='-Wl,'
+	lt_prog_compiler_pic_GCJ='-KPIC'
+	lt_prog_compiler_static_GCJ='-static'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl_GCJ='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static_GCJ='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static_GCJ='-non_shared'
+      ;;
+
+    sco3.2v5*)
+      lt_prog_compiler_pic_GCJ='-Kpic'
+      lt_prog_compiler_static_GCJ='-dn'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      lt_prog_compiler_pic_GCJ='-KPIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl_GCJ='-Qoption ld '
+      lt_prog_compiler_pic_GCJ='-PIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      lt_prog_compiler_pic_GCJ='-KPIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_prog_compiler_pic_GCJ='-Kconform_pic'
+	lt_prog_compiler_static_GCJ='-Bstatic'
+      fi
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic_GCJ='-pic'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared_GCJ=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_GCJ"; then
+
+echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6
+if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_pic_works_GCJ=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_GCJ"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:15396: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:15400: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test ! -s conftest.err; then
+       lt_prog_compiler_pic_works_GCJ=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6
+
+if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then
+    case $lt_prog_compiler_pic_GCJ in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;;
+     esac
+else
+    lt_prog_compiler_pic_GCJ=
+     lt_prog_compiler_can_build_shared_GCJ=no
+fi
+
+fi
+case "$host_os" in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_GCJ=
+    ;;
+  *)
+    lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ"
+    ;;
+esac
+
+echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_c_o_GCJ=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:15456: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:15460: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test ! -s out/conftest.err; then
+       lt_cv_prog_compiler_c_o_GCJ=yes
+     fi
+   fi
+   chmod u+w .
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+
+  runpath_var=
+  allow_undefined_flag_GCJ=
+  enable_shared_with_static_runtimes_GCJ=no
+  archive_cmds_GCJ=
+  archive_expsym_cmds_GCJ=
+  old_archive_From_new_cmds_GCJ=
+  old_archive_from_expsyms_cmds_GCJ=
+  export_dynamic_flag_spec_GCJ=
+  whole_archive_flag_spec_GCJ=
+  thread_safe_flag_spec_GCJ=
+  hardcode_libdir_flag_spec_GCJ=
+  hardcode_libdir_flag_spec_ld_GCJ=
+  hardcode_libdir_separator_GCJ=
+  hardcode_direct_GCJ=no
+  hardcode_minus_L_GCJ=no
+  hardcode_shlibpath_var_GCJ=unsupported
+  link_all_deplibs_GCJ=unknown
+  hardcode_automatic_GCJ=no
+  module_cmds_GCJ=
+  module_expsym_cmds_GCJ=
+  always_export_symbols_GCJ=no
+  export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms_GCJ=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  ld_shlibs_GCJ=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	ld_shlibs_GCJ=no
+	cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_minus_L_GCJ=yes
+
+      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      ld_shlibs_GCJ=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag_GCJ=unsupported
+	# Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	ld_shlibs_GCJ=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      allow_undefined_flag_GCJ=unsupported
+      always_export_symbols_GCJ=no
+      enable_shared_with_static_runtimes_GCJ=yes
+      export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000  ${wl}--out-implib,$lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+	archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris* | sysv5*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+	ld_shlibs_GCJ=no
+	cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs_GCJ=no
+      fi
+      ;;
+
+    sunos4*)
+      archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+  linux*)
+    if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+        tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_cmds_GCJ="$tmp_archive_cmds"
+      supports_anon_versioning=no
+      case `$LD -v 2>/dev/null` in
+        *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+        *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+        *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+        *\ 2.11.*) ;; # other 2.11 versions
+        *) supports_anon_versioning=yes ;;
+      esac
+      if test $supports_anon_versioning = yes; then
+        archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~
+cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+$echo "local: *; };" >> $output_objdir/$libname.ver~
+        $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+      else
+        archive_expsym_cmds_GCJ="$tmp_archive_cmds"
+      fi
+    else
+      ld_shlibs_GCJ=no
+    fi
+    ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+	archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs_GCJ=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs_GCJ" = yes; then
+      runpath_var=LD_RUN_PATH
+      hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir'
+      export_dynamic_flag_spec_GCJ='${wl}--export-dynamic'
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+ 	whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+  	whole_archive_flag_spec_GCJ=
+      fi
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag_GCJ=unsupported
+      always_export_symbols_GCJ=yes
+      archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L_GCJ=yes
+      if test "$GCC" = yes && test -z "$link_static_flag"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct_GCJ=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+	  export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+	  for ld_flag in $LDFLAGS; do
+  	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+  	    aix_use_runtimelinking=yes
+  	    break
+  	  fi
+	  done
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds_GCJ=''
+      hardcode_direct_GCJ=yes
+      hardcode_libdir_separator_GCJ=':'
+      link_all_deplibs_GCJ=yes
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.012|aix4.012.*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" && \
+  	   strings "$collect2name" | grep resolve_lib_name >/dev/null
+	  then
+  	  # We have reworked collect2
+  	  hardcode_direct_GCJ=yes
+	  else
+  	  # We have old collect2
+  	  hardcode_direct_GCJ=unsupported
+  	  # It fails to find uninstalled libraries when the uninstalled
+  	  # path is not listed in the libpath.  Setting hardcode_minus_L
+  	  # to unsupported forces relinking
+  	  hardcode_minus_L_GCJ=yes
+  	  hardcode_libdir_flag_spec_GCJ='-L$libdir'
+  	  hardcode_libdir_separator_GCJ=
+	  fi
+	esac
+	shared_flag='-shared'
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+  	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+  	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+  	if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+  	fi
+	fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols_GCJ=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag_GCJ='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+       hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath"
+	archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag_GCJ="-z nodefs"
+	  archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an empty executable.
+	 cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+	 hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag_GCJ=' ${wl}-bernotok'
+	  allow_undefined_flag_GCJ=' ${wl}-berok'
+	  # -bexpall does not export symbols beginning with underscore (_)
+	  always_export_symbols_GCJ=yes
+	  # Exported symbols can be pulled into shared objects from archives
+	  whole_archive_flag_spec_GCJ=' '
+	  archive_cmds_need_lc_GCJ=yes
+	  # This is similar to how AIX traditionally builds it's shared libraries.
+	  archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_minus_L_GCJ=yes
+      # see comment about different semantics on the GNU ld section
+      ld_shlibs_GCJ=no
+      ;;
+
+    bsdi4*)
+      export_dynamic_flag_spec_GCJ=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec_GCJ=' '
+      allow_undefined_flag_GCJ=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_From_new_cmds_GCJ='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes_GCJ=yes
+      ;;
+
+    darwin* | rhapsody*)
+    if test "$GXX" = yes ; then
+      archive_cmds_need_lc_GCJ=no
+      case "$host_os" in
+      rhapsody* | darwin1.[012])
+	allow_undefined_flag_GCJ='-undefined suppress'
+	;;
+      *) # Darwin 1.3 on
+      if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+      	allow_undefined_flag_GCJ='-flat_namespace -undefined suppress'
+      else
+        case ${MACOSX_DEPLOYMENT_TARGET} in
+          10.[012])
+            allow_undefined_flag_GCJ='-flat_namespace -undefined suppress'
+            ;;
+          10.*)
+            allow_undefined_flag_GCJ='-undefined dynamic_lookup'
+            ;;
+        esac
+      fi
+	;;
+      esac
+    	lt_int_apple_cc_single_mod=no
+    	output_verbose_link_cmd='echo'
+    	if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
+    	  lt_int_apple_cc_single_mod=yes
+    	fi
+    	if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+    	  archive_cmds_GCJ='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+    	else
+        archive_cmds_GCJ='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      fi
+      module_cmds_GCJ='$CC ${wl}-bind_at_load $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
+        if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+          archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        else
+          archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+        fi
+          module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      hardcode_direct_GCJ=no
+      hardcode_automatic_GCJ=yes
+      hardcode_shlibpath_var_GCJ=unsupported
+      whole_archive_flag_spec_GCJ='-all_load $convenience'
+      link_all_deplibs_GCJ=yes
+    else
+      ld_shlibs_GCJ=no
+    fi
+      ;;
+
+    dgux*)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs_GCJ=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec_GCJ='-R$libdir'
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_GCJ=yes
+      hardcode_minus_L_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu)
+      archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec_GCJ='-R$libdir'
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator_GCJ=:
+      hardcode_direct_GCJ=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L_GCJ=yes
+      export_dynamic_flag_spec_GCJ='${wl}-E'
+      ;;
+
+    hpux10* | hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case "$host_cpu" in
+	hppa*64*|ia64*)
+	  archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case "$host_cpu" in
+	hppa*64*|ia64*)
+	  archive_cmds_GCJ='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  ;;
+	*)
+	  archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	case "$host_cpu" in
+	hppa*64*)
+	  hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+	  hardcode_libdir_flag_spec_ld_GCJ='+b $libdir'
+	  hardcode_libdir_separator_GCJ=:
+	  hardcode_direct_GCJ=no
+	  hardcode_shlibpath_var_GCJ=no
+	  ;;
+	ia64*)
+	  hardcode_libdir_flag_spec_GCJ='-L$libdir'
+	  hardcode_direct_GCJ=no
+	  hardcode_shlibpath_var_GCJ=no
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L_GCJ=yes
+	  ;;
+	*)
+	  hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+	  hardcode_libdir_separator_GCJ=:
+	  hardcode_direct_GCJ=yes
+	  export_dynamic_flag_spec_GCJ='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L_GCJ=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir'
+      fi
+      hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_GCJ=:
+      link_all_deplibs_GCJ=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+	archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec_GCJ='-R$libdir'
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    newsos6)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_GCJ=yes
+      hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_GCJ=:
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    openbsd*)
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_GCJ='${wl}-E'
+      else
+       case $host_os in
+	 openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	   archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	   hardcode_libdir_flag_spec_GCJ='-R$libdir'
+	   ;;
+	 *)
+	   archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	   hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
+	   ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_minus_L_GCJ=yes
+      allow_undefined_flag_GCJ=unsupported
+      archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	allow_undefined_flag_GCJ=' -expect_unresolved \*'
+	archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_GCJ=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
+      else
+	allow_undefined_flag_GCJ=' -expect_unresolved \*'
+	archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+	$LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec_GCJ='-rpath $libdir'
+      fi
+      hardcode_libdir_separator_GCJ=:
+      ;;
+
+    sco3.2v5*)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var_GCJ=no
+      export_dynamic_flag_spec_GCJ='${wl}-Bexport'
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ;;
+
+    solaris*)
+      no_undefined_flag_GCJ=' -z text'
+      if test "$GCC" = yes; then
+	archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+	  $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+	archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+  	$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      hardcode_libdir_flag_spec_GCJ='-R$libdir'
+      hardcode_shlibpath_var_GCJ=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+	whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;;
+      esac
+      link_all_deplibs_GCJ=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_direct_GCJ=yes
+      hardcode_minus_L_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct_GCJ=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds_GCJ='$CC -r -o $output$reload_objs'
+	  hardcode_direct_GCJ=no
+        ;;
+	motorola)
+	  archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var_GCJ=no
+      export_dynamic_flag_spec_GCJ='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var_GCJ=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs_GCJ=yes
+      fi
+      ;;
+
+    sysv4.2uw2*)
+      archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_GCJ=yes
+      hardcode_minus_L_GCJ=no
+      hardcode_shlibpath_var_GCJ=no
+      hardcode_runpath_var=yes
+      runpath_var=LD_RUN_PATH
+      ;;
+
+   sysv5OpenUNIX8* | sysv5UnixWare7* |  sysv5uw[78]* | unixware7*)
+      no_undefined_flag_GCJ='${wl}-z ${wl}text'
+      if test "$GCC" = yes; then
+	archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds_GCJ='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    sysv5*)
+      no_undefined_flag_GCJ=' -z text'
+      # $CC -shared without GNU ld will not create a library from C++
+      # object files and a static libstdc++, better avoid it by now
+      archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+  		$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      hardcode_libdir_flag_spec_GCJ=
+      hardcode_shlibpath_var_GCJ=no
+      runpath_var='LD_RUN_PATH'
+      ;;
+
+    uts4*)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    *)
+      ld_shlibs_GCJ=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5
+echo "${ECHO_T}$ld_shlibs_GCJ" >&6
+test "$ld_shlibs_GCJ" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_GCJ" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_GCJ=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_GCJ in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl_GCJ
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ
+        allow_undefined_flag_GCJ=
+        if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+        then
+	  archive_cmds_need_lc_GCJ=no
+        else
+	  archive_cmds_need_lc_GCJ=yes
+        fi
+        allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5
+echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.01* | freebsdelf3.01*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case "$host_cpu" in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # find out which ABI we are using
+  libsuff=
+  case "$host_cpu" in
+  x86_64*|s390x*|powerpc64*)
+    echo '#line 16770 "configure"' > conftest.$ac_ext
+    if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+      case `/usr/bin/file conftest.$ac_objext` in
+      *64-bit*)
+        libsuff=64
+        sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+        ;;
+      esac
+    fi
+    rm -rf conftest*
+    ;;
+  esac
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`$SED -e 's/:,\t/ /g;s/=^=*$//;s/=^= * / /g' /etc/ld.so.conf | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=yes
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action_GCJ=
+if test -n "$hardcode_libdir_flag_spec_GCJ" || \
+   test -n "$runpath_var GCJ" || \
+   test "X$hardcode_automatic_GCJ"="Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct_GCJ" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no &&
+     test "$hardcode_minus_L_GCJ" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_GCJ=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_GCJ=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_GCJ=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5
+echo "${ECHO_T}$hardcode_action_GCJ" >&6
+
+if test "$hardcode_action_GCJ" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+striplib=
+old_striplib=
+echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
+echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+   darwin*)
+       if test -n "$STRIP" ; then
+         striplib="$STRIP -x"
+         echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+       ;;
+   *)
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+    ;;
+  esac
+fi
+
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+   ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+   ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+   ;;
+
+  *)
+    echo "$as_me:$LINENO: checking for shl_load" >&5
+echo $ECHO_N "checking for shl_load... $ECHO_C" >&6
+if test "${ac_cv_func_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shl_load (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shl_load ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+char (*f) () = shl_load;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != shl_load;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_shl_load=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
+echo "${ECHO_T}$ac_cv_func_shl_load" >&6
+if test $ac_cv_func_shl_load = yes; then
+  lt_cv_dlopen="shl_load"
+else
+  echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char shl_load ();
+int
+main ()
+{
+shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
+else
+  echo "$as_me:$LINENO: checking for dlopen" >&5
+echo $ECHO_N "checking for dlopen... $ECHO_C" >&6
+if test "${ac_cv_func_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dlopen (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+char (*f) () = dlopen;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != dlopen;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_dlopen=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
+echo "${ECHO_T}$ac_cv_func_dlopen" >&6
+if test $ac_cv_func_dlopen = yes; then
+  lt_cv_dlopen="dlopen"
+else
+  echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
+echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_svld_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_svld_dlopen=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6
+if test $ac_cv_lib_svld_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
+echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dld_link ();
+int
+main ()
+{
+dld_link ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dld_dld_link=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_dld_link=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6
+if test $ac_cv_lib_dld_dld_link = yes; then
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
+echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 17555 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}
+EOF
+  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self" >&6
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      LDFLAGS="$LDFLAGS $link_static_flag"
+      echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
+echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 17653 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+
+    exit (status);
+}
+EOF
+  if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler_GCJ \
+    CC_GCJ \
+    LD_GCJ \
+    lt_prog_compiler_wl_GCJ \
+    lt_prog_compiler_pic_GCJ \
+    lt_prog_compiler_static_GCJ \
+    lt_prog_compiler_no_builtin_flag_GCJ \
+    export_dynamic_flag_spec_GCJ \
+    thread_safe_flag_spec_GCJ \
+    whole_archive_flag_spec_GCJ \
+    enable_shared_with_static_runtimes_GCJ \
+    old_archive_cmds_GCJ \
+    old_archive_from_new_cmds_GCJ \
+    predep_objects_GCJ \
+    postdep_objects_GCJ \
+    predeps_GCJ \
+    postdeps_GCJ \
+    compiler_lib_search_path_GCJ \
+    archive_cmds_GCJ \
+    archive_expsym_cmds_GCJ \
+    postinstall_cmds_GCJ \
+    postuninstall_cmds_GCJ \
+    old_archive_from_expsyms_cmds_GCJ \
+    allow_undefined_flag_GCJ \
+    no_undefined_flag_GCJ \
+    export_symbols_cmds_GCJ \
+    hardcode_libdir_flag_spec_GCJ \
+    hardcode_libdir_flag_spec_ld_GCJ \
+    hardcode_libdir_separator_GCJ \
+    hardcode_automatic_GCJ \
+    module_cmds_GCJ \
+    module_expsym_cmds_GCJ \
+    lt_cv_prog_compiler_c_o_GCJ \
+    exclude_expsyms_GCJ \
+    include_expsyms_GCJ; do
+
+    case $var in
+    old_archive_cmds_GCJ | \
+    old_archive_from_new_cmds_GCJ | \
+    archive_cmds_GCJ | \
+    archive_expsym_cmds_GCJ | \
+    module_cmds_GCJ | \
+    module_expsym_cmds_GCJ | \
+    old_archive_from_expsyms_cmds_GCJ | \
+    export_symbols_cmds_GCJ | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="$ofile"
+
+  cat <<__EOF__ >> "$cfgfile"
+# ### BEGIN LIBTOOL TAG CONFIG: $tagname
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_GCJ
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# A language-specific compiler.
+CC=$lt_compiler_GCJ
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC_GCJ
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD_GCJ
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_GCJ
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_GCJ
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_GCJ
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds_GCJ
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds_GCJ
+archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds_GCJ
+module_expsym_cmds=$lt_module_expsym_cmds_GCJ
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects_GCJ
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects_GCJ
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps_GCJ
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps_GCJ
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_GCJ
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_GCJ
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_GCJ
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct_GCJ
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L_GCJ
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic_GCJ
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_GCJ
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path_GCJ"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols_GCJ
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_GCJ
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_GCJ
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_GCJ
+
+# ### END LIBTOOL TAG CONFIG: $tagname
+
+__EOF__
+
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+	else
+	  tagname=""
+	fi
+	;;
+
+      RC)
+
+
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+objext_RC=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${RC-"windres"}
+compiler=$CC
+compiler_RC=$CC
+lt_cv_prog_compiler_c_o_RC=yes
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler_RC \
+    CC_RC \
+    LD_RC \
+    lt_prog_compiler_wl_RC \
+    lt_prog_compiler_pic_RC \
+    lt_prog_compiler_static_RC \
+    lt_prog_compiler_no_builtin_flag_RC \
+    export_dynamic_flag_spec_RC \
+    thread_safe_flag_spec_RC \
+    whole_archive_flag_spec_RC \
+    enable_shared_with_static_runtimes_RC \
+    old_archive_cmds_RC \
+    old_archive_from_new_cmds_RC \
+    predep_objects_RC \
+    postdep_objects_RC \
+    predeps_RC \
+    postdeps_RC \
+    compiler_lib_search_path_RC \
+    archive_cmds_RC \
+    archive_expsym_cmds_RC \
+    postinstall_cmds_RC \
+    postuninstall_cmds_RC \
+    old_archive_from_expsyms_cmds_RC \
+    allow_undefined_flag_RC \
+    no_undefined_flag_RC \
+    export_symbols_cmds_RC \
+    hardcode_libdir_flag_spec_RC \
+    hardcode_libdir_flag_spec_ld_RC \
+    hardcode_libdir_separator_RC \
+    hardcode_automatic_RC \
+    module_cmds_RC \
+    module_expsym_cmds_RC \
+    lt_cv_prog_compiler_c_o_RC \
+    exclude_expsyms_RC \
+    include_expsyms_RC; do
+
+    case $var in
+    old_archive_cmds_RC | \
+    old_archive_from_new_cmds_RC | \
+    archive_cmds_RC | \
+    archive_expsym_cmds_RC | \
+    module_cmds_RC | \
+    module_expsym_cmds_RC | \
+    old_archive_from_expsyms_cmds_RC | \
+    export_symbols_cmds_RC | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="$ofile"
+
+  cat <<__EOF__ >> "$cfgfile"
+# ### BEGIN LIBTOOL TAG CONFIG: $tagname
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_RC
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# A language-specific compiler.
+CC=$lt_compiler_RC
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC_RC
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD_RC
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_RC
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_RC
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_RC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds_RC
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds_RC
+archive_expsym_cmds=$lt_archive_expsym_cmds_RC
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds_RC
+module_expsym_cmds=$lt_module_expsym_cmds_RC
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects_RC
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects_RC
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps_RC
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps_RC
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_RC
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_RC
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_RC
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_RC
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct_RC
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L_RC
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_RC
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic_RC
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_RC
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path_RC"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols_RC
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_RC
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_RC
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_RC
+
+# ### END LIBTOOL TAG CONFIG: $tagname
+
+__EOF__
+
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+	;;
+
+      *)
+	{ { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5
+echo "$as_me: error: Unsupported tag name: $tagname" >&2;}
+   { (exit 1); exit 1; }; }
+	;;
+      esac
+
+      # Append the new tag name to the list of available tags.
+      if test -n "$tagname" ; then
+      available_tags="$available_tags $tagname"
+    fi
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  # Now substitute the updated list of available tags.
+  if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then
+    mv "${ofile}T" "$ofile"
+    chmod +x "$ofile"
+  else
+    rm -f "${ofile}T"
+    { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5
+echo "$as_me: error: unable to update list of available tagged configurations." >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+fi
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Prevent multiple expansion
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-psLib or --without-psLib was given.
+if test "${with_psLib+set}" = set; then
+  withval="$with_psLib"
+
+CFLAGS="${CFLAGS=} -I$withval/include"
+LDFLAGS="${LDFLAGS=} -L$withval/lib"
+
+else
+
+CFLAGS="${CFLAGS=} -I$PSLIB_ROOT/include"
+LDFLAGS="${LDFLAGS=} -L$PSLIB_ROOT/lib"
+
+fi;
+
+
+# Check whether --with-sla or --without-sla was given.
+if test "${with_sla+set}" = set; then
+  withval="$with_sla"
+
+CFLAGS="${CFLAGS=} -I$withval/include"
+LDFLAGS="${LDFLAGS=} -L$withval/lib"
+
+fi;
+
+
+# Check whether --with-cfitsio or --without-cfitsio was given.
+if test "${with_cfitsio+set}" = set; then
+  withval="$with_cfitsio"
+
+CFLAGS="${CFLAGS=} -I$withval/include"
+LDFLAGS="${LDFLAGS=} -L$withval/lib"
+
+fi;
+
+
+# Check whether --with-fftw3 or --without-fftw3 was given.
+if test "${with_fftw3+set}" = set; then
+  withval="$with_fftw3"
+
+CFLAGS="${CFLAGS=} -I$withval/include"
+LDFLAGS="${LDFLAGS=} -L$withval/lib"
+
+fi;
+
+
+# Check whether --with-gsl or --without-gsl was given.
+if test "${with_gsl+set}" = set; then
+  withval="$with_gsl"
+
+# Extract the first word of "$withval/bin/gsl-config", so it can be a program name with args.
+set dummy $withval/bin/gsl-config; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_GSL_CONFIG+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$GSL_CONFIG"; then
+  ac_cv_prog_GSL_CONFIG="$GSL_CONFIG" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_GSL_CONFIG="$withval/bin/gsl-config"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+GSL_CONFIG=$ac_cv_prog_GSL_CONFIG
+if test -n "$GSL_CONFIG"; then
+  echo "$as_me:$LINENO: result: $GSL_CONFIG" >&5
+echo "${ECHO_T}$GSL_CONFIG" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+else
+
+# Extract the first word of "gsl-config", so it can be a program name with args.
+set dummy gsl-config; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_GSL_CONFIG+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$GSL_CONFIG"; then
+  ac_cv_prog_GSL_CONFIG="$GSL_CONFIG" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_GSL_CONFIG="`which gsl-config`"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+GSL_CONFIG=$ac_cv_prog_GSL_CONFIG
+if test -n "$GSL_CONFIG"; then
+  echo "$as_me:$LINENO: result: $GSL_CONFIG" >&5
+echo "${ECHO_T}$GSL_CONFIG" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+fi;
+if test "$GSL_CONFIG" != ""
+then
+    GSL_PREFIX="`${GSL_CONFIG} --prefix`"
+    GSL_LIBS="`${GSL_CONFIG} --libs`"
+    LDFLAGS="${LDFLAGS=} -L$GSL_PREFIX/lib$GSL_LIBS"
+    CFLAGS="${CFLAGS=} -I$GSL_PREFIX/include"
+fi
+
+
+echo "$as_me:$LINENO: checking for main in -lsla" >&5
+echo $ECHO_N "checking for main in -lsla... $ECHO_C" >&6
+if test "${ac_cv_lib_sla_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsla  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_sla_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_sla_main=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_sla_main" >&5
+echo "${ECHO_T}$ac_cv_lib_sla_main" >&6
+if test $ac_cv_lib_sla_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBSLA 1
+_ACEOF
+
+  LIBS="-lsla $LIBS"
+
+else
+  { { echo "$as_me:$LINENO: error: SLA library required" >&5
+echo "$as_me: error: SLA library required" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+echo "$as_me:$LINENO: checking for main in -lcfitsio" >&5
+echo $ECHO_N "checking for main in -lcfitsio... $ECHO_C" >&6
+if test "${ac_cv_lib_cfitsio_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcfitsio  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_cfitsio_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_cfitsio_main=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_cfitsio_main" >&5
+echo "${ECHO_T}$ac_cv_lib_cfitsio_main" >&6
+if test $ac_cv_lib_cfitsio_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCFITSIO 1
+_ACEOF
+
+  LIBS="-lcfitsio $LIBS"
+
+else
+  { { echo "$as_me:$LINENO: error: CFITSIO library required" >&5
+echo "$as_me: error: CFITSIO library required" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+echo "$as_me:$LINENO: checking for main in -lfftw3f" >&5
+echo $ECHO_N "checking for main in -lfftw3f... $ECHO_C" >&6
+if test "${ac_cv_lib_fftw3f_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lfftw3f  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_fftw3f_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_fftw3f_main=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_fftw3f_main" >&5
+echo "${ECHO_T}$ac_cv_lib_fftw3f_main" >&6
+if test $ac_cv_lib_fftw3f_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBFFTW3F 1
+_ACEOF
+
+  LIBS="-lfftw3f $LIBS"
+
+else
+  { { echo "$as_me:$LINENO: error: FFTW3 library required" >&5
+echo "$as_me: error: FFTW3 library required" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+echo "$as_me:$LINENO: checking for main in -lgsl" >&5
+echo $ECHO_N "checking for main in -lgsl... $ECHO_C" >&6
+if test "${ac_cv_lib_gsl_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gsl_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gsl_main=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gsl_main" >&5
+echo "${ECHO_T}$ac_cv_lib_gsl_main" >&6
+if test $ac_cv_lib_gsl_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBGSL 1
+_ACEOF
+
+  LIBS="-lgsl $LIBS"
+
+else
+  { { echo "$as_me:$LINENO: error: GSL library required" >&5
+echo "$as_me: error: GSL library required" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+echo "$as_me:$LINENO: checking for main in -lgslcblas" >&5
+echo $ECHO_N "checking for main in -lgslcblas... $ECHO_C" >&6
+if test "${ac_cv_lib_gslcblas_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgslcblas  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gslcblas_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gslcblas_main=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gslcblas_main" >&5
+echo "${ECHO_T}$ac_cv_lib_gslcblas_main" >&6
+if test $ac_cv_lib_gslcblas_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBGSLCBLAS 1
+_ACEOF
+
+  LIBS="-lgslcblas $LIBS"
+
+else
+  { { echo "$as_me:$LINENO: error: GSL CBLAS library required" >&5
+echo "$as_me: error: GSL CBLAS library required" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+echo "$as_me:$LINENO: checking for main in -lpslib" >&5
+echo $ECHO_N "checking for main in -lpslib... $ECHO_C" >&6
+if test "${ac_cv_lib_pslib_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpslib  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pslib_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pslib_main=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pslib_main" >&5
+echo "${ECHO_T}$ac_cv_lib_pslib_main" >&6
+if test $ac_cv_lib_pslib_main = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBPSLIB 1
+_ACEOF
+
+  LIBS="-lpslib $LIBS"
+
+else
+  { { echo "$as_me:$LINENO: error: psLib library required" >&5
+echo "$as_me: error: psLib library required" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+                              ac_config_files="$ac_config_files Makefile src/Makefile test/Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+        "s/'/'\\\\''/g;
+    	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[ 	]*VPATH[ 	]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[ 	]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[ 	]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+         sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.57.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.57,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+#
+# INIT-COMMANDS section.
+#
+
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+_ACEOF
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+  "test/Makefile" ) CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
+  "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+  "src/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@CYGPATH_W@,$CYGPATH_W,;t t
+s,@PACKAGE@,$PACKAGE,;t t
+s,@VERSION@,$VERSION,;t t
+s,@ACLOCAL@,$ACLOCAL,;t t
+s,@AUTOCONF@,$AUTOCONF,;t t
+s,@AUTOMAKE@,$AUTOMAKE,;t t
+s,@AUTOHEADER@,$AUTOHEADER,;t t
+s,@MAKEINFO@,$MAKEINFO,;t t
+s,@AMTAR@,$AMTAR,;t t
+s,@install_sh@,$install_sh,;t t
+s,@STRIP@,$STRIP,;t t
+s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
+s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
+s,@mkdir_p@,$mkdir_p,;t t
+s,@AWK@,$AWK,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@am__leading_dot@,$am__leading_dot,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@DEPDIR@,$DEPDIR,;t t
+s,@am__include@,$am__include,;t t
+s,@am__quote@,$am__quote,;t t
+s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t
+s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
+s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
+s,@CCDEPMODE@,$CCDEPMODE,;t t
+s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
+s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@EGREP@,$EGREP,;t t
+s,@LN_S@,$LN_S,;t t
+s,@ECHO@,$ECHO,;t t
+s,@AR@,$AR,;t t
+s,@ac_ct_AR@,$ac_ct_AR,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@CPP@,$CPP,;t t
+s,@CXX@,$CXX,;t t
+s,@CXXFLAGS@,$CXXFLAGS,;t t
+s,@ac_ct_CXX@,$ac_ct_CXX,;t t
+s,@CXXDEPMODE@,$CXXDEPMODE,;t t
+s,@am__fastdepCXX_TRUE@,$am__fastdepCXX_TRUE,;t t
+s,@am__fastdepCXX_FALSE@,$am__fastdepCXX_FALSE,;t t
+s,@CXXCPP@,$CXXCPP,;t t
+s,@F77@,$F77,;t t
+s,@FFLAGS@,$FFLAGS,;t t
+s,@ac_ct_F77@,$ac_ct_F77,;t t
+s,@LIBTOOL@,$LIBTOOL,;t t
+s,@GSL_CONFIG@,$GSL_CONFIG,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+  	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+  	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+        cat >$tmp/stdin
+        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_file" : 'X\(//\)[^/]' \| \
+         X"$ac_file" : 'X\(//\)$' \| \
+         X"$ac_file" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$as_dir" : 'X\(//\)[^/]' \| \
+         X"$as_dir" : 'X\(//\)$' \| \
+         X"$as_dir" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+         # Absolute (can't be DOS-style, as IFS=:)
+         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         echo $f;;
+      *) # Relative
+         if test -f "$f"; then
+           # Build tree
+           echo $f
+         elif test -f "$srcdir/$f"; then
+           # Source tree
+           echo $srcdir/$f
+         else
+           # /dev/null tree
+           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([ 	]*\)#\([ 	]*define[ 	][ 	]*\)'
+ac_dB='[ 	].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+        cat >$tmp/stdin
+        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+         # Absolute (can't be DOS-style, as IFS=:)
+         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         echo $f;;
+      *) # Relative
+         if test -f "$f"; then
+           # Build tree
+           echo $f
+         elif test -f "$srcdir/$f"; then
+           # Source tree
+           echo $srcdir/$f
+         else
+           # /dev/null tree
+           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[ 	]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[ 	]*#[ 	]*define[ 	][ 	]*\([^ 	(][^ 	(]*\)\(([^)]*)\)[ 	]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[ 	]*#[ 	]*define[ 	][ 	]*\([^ 	][^ 	]*\)[ 	]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[ 	]*#[ 	]*undef[ 	][ 	]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[ 	]*#[ 	]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[ 	]*#[ 	]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[ 	]*#[ 	]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_file" : 'X\(//\)[^/]' \| \
+         X"$ac_file" : 'X\(//\)$' \| \
+         X"$ac_file" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$as_dir" : 'X\(//\)[^/]' \| \
+         X"$as_dir" : 'X\(//\)$' \| \
+         X"$as_dir" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+# Compute $ac_file's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $ac_file | $ac_file:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
+$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X$ac_file : 'X\(//\)[^/]' \| \
+         X$ac_file : 'X\(//\)$' \| \
+         X$ac_file : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X$ac_file |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`/stamp-h$_am_stamp_count
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_COMMANDS section.
+#
+for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
+  ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
+  ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+  ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_dest" : 'X\(//\)[^/]' \| \
+         X"$ac_dest" : 'X\(//\)$' \| \
+         X"$ac_dest" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+  { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+echo "$as_me: executing $ac_dest commands" >&6;}
+  case $ac_dest in
+    depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
+  # Strip MF so we end up with the name of the file.
+  mf=`echo "$mf" | sed -e 's/:.*$//'`
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+    dirpart=`(dirname "$mf") 2>/dev/null ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$mf" : 'X\(//\)[^/]' \| \
+         X"$mf" : 'X\(//\)$' \| \
+         X"$mf" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  else
+    continue
+  fi
+  grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue
+  # Extract the definition of DEP_FILES from the Makefile without
+  # running `make'.
+  DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+  test -z "$DEPDIR" && continue
+  # When using ansi2knr, U may be empty or an underscore; expand it
+  U=`sed -n 's/^U = //p' < "$mf"`
+  test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+  # We invoke sed twice because it is the simplest approach to
+  # changing $(DEPDIR) to its actual value in the expansion.
+  for file in `sed -n '
+    /^DEP_FILES = .*\\\\$/ {
+      s/^DEP_FILES = //
+      :loop
+	s/\\\\$//
+	p
+	n
+	/\\\\$/ b loop
+      p
+    }
+    /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+       sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+    # Make sure the directory exists.
+    test -f "$dirpart/$file" && continue
+    fdir=`(dirname "$file") 2>/dev/null ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$file" : 'X\(//\)[^/]' \| \
+         X"$file" : 'X\(//\)$' \| \
+         X"$file" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    { if $as_mkdir_p; then
+    mkdir -p $dirpart/$fdir
+  else
+    as_dir=$dirpart/$fdir
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$as_dir" : 'X\(//\)[^/]' \| \
+         X"$as_dir" : 'X\(//\)$' \| \
+         X"$as_dir" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
+echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+    # echo "creating $dirpart/$file"
+    echo '# dummy' > "$dirpart/$file"
+  done
+done
+ ;;
+  esac
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
Index: /branches/rel3/psModules/configure.in
===================================================================
--- /branches/rel3/psModules/configure.in	(revision 2163)
+++ /branches/rel3/psModules/configure.in	(revision 2163)
@@ -0,0 +1,66 @@
+AC_INIT(configure.in)
+
+AM_CONFIG_HEADER(src/config.h)
+AM_INIT_AUTOMAKE(psModule, 0.1)
+
+AC_LANG(C)
+AC_PROG_CC
+
+dnl AC_SUBST(LDFLAGS)
+AC_SUBST(CFLAGS)
+
+CFLAGS="${CFLAGS=} -g2 -Wall -std=c99 -D_GNU_SOURCE"
+
+AC_PROG_INSTALL
+AM_PROG_LIBTOOL
+
+AC_ARG_WITH(psLib,
+[  --with-psLib=DIR        Specify location of psLib files],[
+CFLAGS="${CFLAGS=} -I$withval/include"
+LDFLAGS="${LDFLAGS=} -L$withval/lib"
+],[
+CFLAGS="${CFLAGS=} -I$PSLIB_ROOT/include"
+LDFLAGS="${LDFLAGS=} -L$PSLIB_ROOT/lib"
+])
+
+AC_ARG_WITH(sla,
+[  --with-sla=DIR          Specify location of SLA.],[
+CFLAGS="${CFLAGS=} -I$withval/include"
+LDFLAGS="${LDFLAGS=} -L$withval/lib"
+])
+
+AC_ARG_WITH(cfitsio,
+[  --with-cfitsio=DIR      Specify location of CFITSIO.],[
+CFLAGS="${CFLAGS=} -I$withval/include"
+LDFLAGS="${LDFLAGS=} -L$withval/lib"
+])
+
+AC_ARG_WITH(fftw3,
+[  --with-fftw3=DIR        Specify location of FFTW version 3.],[
+CFLAGS="${CFLAGS=} -I$withval/include"
+LDFLAGS="${LDFLAGS=} -L$withval/lib"
+])
+
+AC_ARG_WITH(gsl,
+[  --with-gsl=DIR          Specify location of GSL.],[
+AC_CHECK_PROG(GSL_CONFIG, $withval/bin/gsl-config, $withval/bin/gsl-config)
+],[
+AC_CHECK_PROG(GSL_CONFIG, gsl-config, `which gsl-config`)
+])
+if test "$GSL_CONFIG" != ""
+then
+    GSL_PREFIX="`${GSL_CONFIG} --prefix`"
+    GSL_LIBS="`${GSL_CONFIG} --libs`"
+    LDFLAGS="${LDFLAGS=} -L$GSL_PREFIX/lib$GSL_LIBS"
+    CFLAGS="${CFLAGS=} -I$GSL_PREFIX/include"
+fi
+
+dnl Check the libraries to see if they exist, etc.
+AC_CHECK_LIB(sla,main,,AC_MSG_ERROR(SLA library required))
+AC_CHECK_LIB(cfitsio,main,,AC_MSG_ERROR(CFITSIO library required))
+AC_CHECK_LIB(fftw3f,main,,AC_MSG_ERROR(FFTW3 library required))
+AC_CHECK_LIB(gsl,main,,AC_MSG_ERROR(GSL library required))
+AC_CHECK_LIB(gslcblas,main,,AC_MSG_ERROR(GSL CBLAS library required))
+AC_CHECK_LIB(pslib,main,,AC_MSG_ERROR(psLib library required))
+
+AC_OUTPUT(Makefile src/Makefile test/Makefile)
Index: /branches/rel3/psModules/depcomp
===================================================================
--- /branches/rel3/psModules/depcomp	(revision 2163)
+++ /branches/rel3/psModules/depcomp	(revision 2163)
@@ -0,0 +1,441 @@
+#! /bin/sh
+
+# depcomp - compile a program generating dependencies as side-effects
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+# `libtool' can also be set to `yes' or `no'.
+
+depfile=${depfile-`echo "$object" | sed 's,\([^/]*\)$,.deps/\1,;s/\.\([^.]*\)$/.P\1/'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+  "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> $depfile
+    echo >> $depfile
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> $depfile
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  This file always lives in the current directory.
+  # Also, the AIX compiler puts `$object:' at the start of each line;
+  # $object doesn't have directory information.
+  stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
+  tmpdepfile="$stripped.u"
+  outname="$stripped.o"
+  if test "$libtool" = yes; then
+    "$@" -Wc,-M
+  else
+    "$@" -M
+  fi
+
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Must come before tru64.
+
+  # Intel's C compiler understands `-MD -MF file'.  However
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed -e "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  sed -e "s,^[^:]*: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+tru64)
+   # The Tru64 AIX compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put 
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+
+   tmpdepfile1="$object.d"
+   tmpdepfile2=`echo "$object" | sed -e 's/.o$/.d/'` 
+   if test "$libtool" = yes; then
+      "$@" -Wc,-MD
+   else
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2"
+      exit $stat
+   fi
+
+   if test -f "$tmpdepfile1"; then
+      tmpdepfile="$tmpdepfile1"
+   else
+      tmpdepfile="$tmpdepfile2"
+   fi
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a space and a tab in the [].
+      sed -e 's,^.*\.[a-z]*:[ 	]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the proprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  test -z "$dashmflag" && dashmflag=-M
+  ( IFS=" "
+    case " $* " in
+    *" --mode=compile "*) # this is libtool, let us make it quiet
+      for arg
+      do # cycle over the arguments
+        case "$arg" in
+	"--mode=compile")
+	  # insert --quiet before "--mode=compile"
+	  set fnord "$@" --quiet
+	  shift # fnord
+	  ;;
+	esac
+	set fnord "$@" "$arg"
+	shift # fnord
+	shift # "$arg"
+      done
+      ;;
+    esac
+    "$@" $dashmflag | sed 's:^[^:]*\:[ 	]*:'"$object"'\: :' > "$tmpdepfile"
+  ) &
+  proc=$!
+  "$@"
+  stat=$?
+  wait "$proc"
+  if test "$stat" != 0; then exit $stat; fi
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  # X makedepend
+  (
+    shift
+    cleared=no
+    for arg in "$@"; do
+      case $cleared in no)
+        set ""; shift
+	cleared=yes
+      esac
+      case "$arg" in
+        -D*|-I*)
+	  set fnord "$@" "$arg"; shift;;
+	-*)
+	  ;;
+	*)
+	  set fnord "$@" "$arg"; shift;;
+      esac
+    done
+    obj_suffix="`echo $object | sed 's/^.*\././'`"
+    touch "$tmpdepfile"
+    ${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  ) &
+  proc=$!
+  "$@"
+  stat=$?
+  wait "$proc"
+  if test "$stat" != 0; then exit $stat; fi
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tail +3 "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the proprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  ( IFS=" "
+    case " $* " in
+    *" --mode=compile "*)
+      for arg
+      do # cycle over the arguments
+        case $arg in
+	"--mode=compile")
+	  # insert --quiet before "--mode=compile"
+	  set fnord "$@" --quiet
+	  shift # fnord
+	  ;;
+	esac
+	set fnord "$@" "$arg"
+	shift # fnord
+	shift # "$arg"
+      done
+      ;;
+    esac
+    "$@" -E |
+    sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  ) &
+  proc=$!
+  "$@"
+  stat=$?
+  wait "$proc"
+  if test "$stat" != 0; then exit $stat; fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the proprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  ( IFS=" "
+    case " $* " in
+    *" --mode=compile "*)
+      for arg
+      do # cycle over the arguments
+        case $arg in
+	"--mode=compile")
+	  # insert --quiet before "--mode=compile"
+	  set fnord "$@" --quiet
+	  shift # fnord
+	  ;;
+	esac
+	set fnord "$@" "$arg"
+	shift # fnord
+	shift # "$arg"
+      done
+      ;;
+    esac
+    "$@" -E |
+    sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+  ) &
+  proc=$!
+  "$@"
+  stat=$?
+  wait "$proc"
+  if test "$stat" != 0; then exit $stat; fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::	\1 \\:p' >> "$depfile"
+  echo "	" >> "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
Index: /branches/rel3/psModules/install-sh
===================================================================
--- /branches/rel3/psModules/install-sh	(revision 2163)
+++ /branches/rel3/psModules/install-sh	(revision 2163)
@@ -0,0 +1,276 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd=$cpprog
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd=$stripprog
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "$0: no input file specified" >&2
+	exit 1
+else
+	:
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+
+	if [ -d "$dst" ]; then
+		instcmd=:
+		chmodcmd=""
+	else
+		instcmd=$mkdirprog
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f "$src" ] || [ -d "$src" ]
+	then
+		:
+	else
+		echo "$0: $src does not exist" >&2
+		exit 1
+	fi
+
+	if [ x"$dst" = x ]
+	then
+		echo "$0: no destination specified" >&2
+		exit 1
+	else
+		:
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d "$dst" ]
+	then
+		dst=$dst/`basename "$src"`
+	else
+		:
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+	'
+IFS="${IFS-$defaultIFS}"
+
+oIFS=$IFS
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS=$oIFS
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp=$pathcomp$1
+	shift
+
+	if [ ! -d "$pathcomp" ] ;
+        then
+		$mkdirprog "$pathcomp"
+	else
+		:
+	fi
+
+	pathcomp=$pathcomp/
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd "$dst" &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ]
+	then
+		dstfile=`basename "$dst"`
+	else
+		dstfile=`basename "$dst" $transformbasename |
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ]
+	then
+		dstfile=`basename "$dst"`
+	else
+		:
+	fi
+
+# Make a couple of temp file names in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+	rmtmp=$dstdir/#rm.$$#
+
+# Trap to clean up temp files at exit.
+
+	trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
+	trap '(exit $?); exit' 1 2 13 15
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd "$src" "$dsttmp" &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
+
+# Now remove or move aside any old file at destination location.  We try this
+# two ways since rm can't unlink itself on some systems and the destination
+# file might be busy for other reasons.  In this case, the final cleanup
+# might fail but the new file should still install successfully.
+
+{
+	if [ -f "$dstdir/$dstfile" ]
+	then
+		$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
+		$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
+		{
+		  echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+		  (exit 1); exit
+		}
+	else
+		:
+	fi
+} &&
+
+# Now rename the file to the real destination.
+
+	$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+
+fi &&
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+
+{
+	(exit 0); exit
+}
Index: /branches/rel3/psModules/ltmain.sh
===================================================================
--- /branches/rel3/psModules/ltmain.sh	(revision 2163)
+++ /branches/rel3/psModules/ltmain.sh	(revision 2163)
@@ -0,0 +1,6343 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun configure.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003
+# Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell, and then maybe $echo will work.
+  exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# The name of this program.
+progname=`$echo "$0" | ${SED} 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.5a
+TIMESTAMP=" (1.1240 2003/06/26 06:55:19)"
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+# test EBCDIC or ASCII
+case `echo A|tr A '\301'` in
+ A) # EBCDIC based system
+  SP2NL="tr '\100' '\n'"
+  NL2SP="tr '\r\n' '\100\100'"
+  ;;
+ *) # Assume ASCII based system
+  SP2NL="tr '\040' '\012'"
+  NL2SP="tr '\015\012' '\040\040'"
+  ;;
+esac
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+  save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+  save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+# Make sure IFS has a sensible default
+: ${IFS=" 	"}
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  $echo "$modename: not configured to build any kind of library" 1>&2
+  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+#####################################
+# Shell function definitions:
+# This seems to be the best place for them
+
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+win32_libid () {
+  win32_libid_type="unknown"
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
+      grep -E 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
+      win32_nmres=`eval $NM -f posix -A $1 | \
+	sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'`
+      if test "X$win32_nmres" = "Ximport" ; then
+        win32_libid_type="x86 archive import"
+      else
+        win32_libid_type="x86 archive static"
+      fi
+    fi
+    ;;
+  *DLL*) 
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $echo $win32_libid_type
+}
+
+# End of Shell function definitions
+#####################################
+
+# Parse our command line options once, thoroughly.
+while test "$#" -gt 0
+do
+  arg="$1"
+  shift
+
+  case $arg in
+  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case $prev in
+    execute_dlfiles)
+      execute_dlfiles="$execute_dlfiles $arg"
+      ;;
+    tag)
+      tagname="$arg"
+
+      # Check whether tagname contains only valid characters
+      case $tagname in
+      *[!-_A-Za-z0-9,/]*)
+	$echo "$progname: invalid tag name: $tagname" 1>&2
+	exit 1
+	;;
+      esac
+
+      case $tagname in
+      CC)
+	# Don't test for the "default" C tag, as we know, it's there, but
+	# not specially marked.
+	;;
+      *)
+	if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$0" > /dev/null; then
+	  taglist="$taglist $tagname"
+	  # Evaluate the configuration.
+	  eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $0`"
+	else
+	  $echo "$progname: ignoring unknown tag $tagname" 1>&2
+	fi
+	;;
+      esac
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case $arg in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+    $echo
+    $echo "Copyright (C) 2003  Free Software Foundation, Inc."
+    $echo "This is free software; see the source for copying conditions.  There is NO"
+    $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+    exit 0
+    ;;
+
+  --config)
+    ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$0"
+    done
+    exit 0
+    ;;
+
+  --debug)
+    $echo "$progname: enabling shell trace mode"
+    set -x
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    $echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      $echo "enable shared libraries"
+    else
+      $echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      $echo "enable static libraries"
+    else
+      $echo "disable static libraries"
+    fi
+    exit 0
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --preserve-dup-deps) duplicate_deps="yes" ;;
+
+  --quiet | --silent)
+    show=:
+    ;;
+
+  --tag) prevopt="--tag" prev=tag ;;
+  --tag=*)
+    set tag "$optarg" ${1+"$@"}
+    shift
+    prev=tag
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$modename: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+fi
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2
+    $echo "*** Future versions of Libtool will require -mode=MODE be specified." 1>&2
+    case $nonopt in
+    *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*)
+      mode=link
+      for arg
+      do
+	case $arg in
+	-c)
+	   mode=compile
+	   break
+	   ;;
+	esac
+      done
+      ;;
+    *db | *dbx | *strace | *truss)
+      mode=execute
+      ;;
+    *install*|cp|mv)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+	if test -n "$nonopt"; then
+	  $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+	else
+	  $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+	fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$modename --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case $mode in
+  # libtool compile mode
+  compile)
+    modename="$modename: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
+    suppress_output=
+    arg_mode=normal
+    libobj=
+
+    for arg
+    do
+      case "$arg_mode" in
+      arg  )
+	# do not "continue".  Instead, add this to base_compile
+	lastarg="$arg"
+	arg_mode=normal
+	;;
+
+      target )
+	libobj="$arg"
+	arg_mode=normal
+	continue
+	;;
+
+      normal )
+	# Accept any command-line options.
+	case $arg in
+	-o)
+	  if test -n "$libobj" ; then
+	    $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+	    exit 1
+	  fi
+	  arg_mode=target
+	  continue
+	  ;;
+
+	-static)
+	  build_old_libs=yes
+	  continue
+	  ;;
+
+	-prefer-pic)
+	  pic_mode=yes
+	  continue
+	  ;;
+
+	-prefer-non-pic)
+	  pic_mode=no
+	  continue
+	  ;;
+
+	-Xcompiler)
+	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
+	  continue      #  The current "srcfile" will either be retained or
+	  ;;            #  replaced later.  I would guess that would be a bug.
+
+	-Wc,*)
+	  args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
+	  lastarg=
+	  save_ifs="$IFS"; IFS=','
+	  for arg in $args; do
+	    IFS="$save_ifs"
+
+	    # Double-quote args containing other shell metacharacters.
+	    # Many Bourne shells cannot handle close brackets correctly
+	    # in scan sets, so we specify it separately.
+	    case $arg in
+	      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	      arg="\"$arg\""
+	      ;;
+	    esac
+	    lastarg="$lastarg $arg"
+	  done
+	  IFS="$save_ifs"
+	  lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
+
+	  # Add the arguments to base_compile.
+	  base_compile="$base_compile $lastarg"
+	  continue
+	  ;;
+
+	* )
+	  # Accept the current argument as the source file.
+	  # The previous "srcfile" becomes the current argument.
+	  #
+	  lastarg="$srcfile"
+	  srcfile="$arg"
+	  ;;
+	esac  #  case $arg
+	;;
+      esac    #  case $arg_mode
+
+      # Aesthetically quote the previous argument.
+      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+      case $lastarg in
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	lastarg="\"$lastarg\""
+	;;
+      esac
+
+      base_compile="$base_compile $lastarg"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      $echo "$modename: you must specify an argument for -Xcompile"
+      exit 1
+      ;;
+    target)
+      $echo "$modename: you must specify a target with \`-o'" 1>&2
+      exit 1
+      ;;
+    *)
+      # Get the name of the library object.
+      [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    xform='[cCFSifmso]'
+    case $libobj in
+    *.ada) xform=ada ;;
+    *.adb) xform=adb ;;
+    *.ads) xform=ads ;;
+    *.asm) xform=asm ;;
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.ii) xform=ii ;;
+    *.class) xform=class ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.f90) xform=f90 ;;
+    *.for) xform=for ;;
+    *.java) xform=java ;;
+    esac
+
+    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+    case $libobj in
+    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+    *)
+      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    # Infer tagged configuration to use if any are available and
+    # if one wasn't chosen via the "--tag" command line option.
+    # Only attempt this if the compiler in the base compile
+    # command doesn't match the default compiler.
+    if test -n "$available_tags" && test -z "$tagname"; then
+      case $base_compile in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+	for z in $available_tags; do
+	  if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$0" > /dev/null; then
+	    # Evaluate the configuration.
+	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $0`"
+	    case "$base_compile " in
+	    "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*)
+	      # The compiler in the base compile command matches
+	      # the one in the tagged configuration.
+	      # Assume this is the tagged configuration we want.
+	      tagname=$z
+	      break
+	      ;;
+	    esac
+	  fi
+	done
+	# If $tagname still isn't set, then no tagged configuration
+	# was found and let the user know that the "--tag" command
+	# line option must be used.
+	if test -z "$tagname"; then
+	  $echo "$modename: unable to infer tagged configuration"
+	  $echo "$modename: specify a tag with \`--tag'" 1>&2
+	  exit 1
+#        else
+#          $echo "$modename: using $tagname tagged configuration"
+	fi
+	;;
+      esac
+    fi
+
+    objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+    xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+    if test "X$xdir" = "X$obj"; then
+      xdir=
+    else
+      xdir=$xdir/
+    fi
+    lobj=${xdir}$objdir/$objname
+
+    if test -z "$base_compile"; then
+      $echo "$modename: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
+
+    $run $rm $removelist
+    trap "$run $rm $removelist; exit 1" 1 2 15
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2*)
+      pic_mode=default
+      ;;
+    esac
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+      removelist="$removelist $output_obj $lockfile"
+      trap "$run $rm $removelist; exit 1" 1 2 15
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until $run ln "$0" "$lockfile" 2>/dev/null; do
+	$show "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+	$echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit 1
+      fi
+      $echo $srcfile > "$lockfile"
+    fi
+
+    if test -n "$fix_srcfile_path"; then
+      eval srcfile=\"$fix_srcfile_path\"
+    fi
+
+    $run $rm "$libobj" "${libobj}T"
+
+    # Create a libtool object file (analogous to a ".la" file),
+    # but don't create it if we're doing a dry run.
+    test -z "$run" && cat > ${libobj}T <<EOF
+# $libobj - a libtool object file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+EOF
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test "$pic_mode" != no; then
+	command="$base_compile $srcfile $pic_flag"
+      else
+	# Don't build PIC code
+	command="$base_compile $srcfile"
+      fi
+
+      if test ! -d "${xdir}$objdir"; then
+	$show "$mkdir ${xdir}$objdir"
+	$run $mkdir ${xdir}$objdir
+	status=$?
+	if test "$status" -ne 0 && test ! -d "${xdir}$objdir"; then
+	  exit $status
+	fi
+      fi
+
+      if test -z "$output_obj"; then
+	# Place PIC objects in $objdir
+	command="$command -o $lobj"
+      fi
+
+      $run $rm "$lobj" "$output_obj"
+
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+	test -n "$output_obj" && $run $rm $removelist
+	exit 1
+      fi
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit 1
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+	$show "$mv $output_obj $lobj"
+	if $run $mv $output_obj $lobj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # Append the name of the PIC object to the libtool object file.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object='$objdir/$objname'
+
+EOF
+
+      # Allow error messages only from the first compilation.
+      suppress_output=' >/dev/null 2>&1'
+    else
+      # No PIC object so indicate it doesn't exist in the libtool
+      # object file.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object=none
+
+EOF
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
+	# Don't build PIC code
+	command="$base_compile $srcfile"
+      else
+	command="$base_compile $srcfile $pic_flag"
+      fi
+      if test "$compiler_c_o" = yes; then
+	command="$command -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      command="$command$suppress_output"
+      $run $rm "$obj" "$output_obj"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+	$run $rm $removelist
+	exit 1
+      fi
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$run $rm $removelist
+	exit 1
+      fi
+
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+	$show "$mv $output_obj $obj"
+	if $run $mv $output_obj $obj; then :
+	else
+	  error=$?
+	  $run $rm $removelist
+	  exit $error
+	fi
+      fi
+
+      # Append the name of the non-PIC object the libtool object file.
+      # Only append if the libtool object file exists.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object='$objname'
+
+EOF
+    else
+      # Append the name of the non-PIC object the libtool object file.
+      # Only append if the libtool object file exists.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object=none
+
+EOF
+    fi
+
+    $run $mv "${libobj}T" "${libobj}"
+
+    # Unlock the critical section if it was locked
+    if test "$need_locks" != no; then
+      $run $rm "$lockfile"
+    fi
+
+    exit 0
+    ;;
+
+  # libtool link mode
+  link | relink)
+    modename="$modename: link"
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args="$nonopt"
+    base_compile="$nonopt"
+    compile_command="$nonopt"
+    finalize_command="$nonopt"
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    add_flags=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+
+    avoid_version=no
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    non_pic_objects=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -all-static | -static)
+	if test "X$arg" = "X-all-static"; then
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+	    $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	else
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	fi
+	build_libtool_libs=no
+	build_old_libs=yes
+	prefer_static_libs=yes
+	break
+	;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg="$1"
+      base_compile="$base_compile $arg"
+      shift
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
+	;;
+      *) qarg=$arg ;;
+      esac
+      libtool_args="$libtool_args $qarg"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case $prev in
+	output)
+	  compile_command="$compile_command @OUTPUT@"
+	  finalize_command="$finalize_command @OUTPUT@"
+	  ;;
+	esac
+
+	case $prev in
+	dlfiles|dlprefiles)
+	  if test "$preload" = no; then
+	    # Add the symbol object into the linking commands.
+	    compile_command="$compile_command @SYMFILE@"
+	    finalize_command="$finalize_command @SYMFILE@"
+	    preload=yes
+	  fi
+	  case $arg in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  force)
+	    if test "$dlself" = no; then
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  self)
+	    if test "$prev" = dlprefiles; then
+	      dlself=yes
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test "$prev" = dlfiles; then
+	      dlfiles="$dlfiles $arg"
+	    else
+	      dlprefiles="$dlprefiles $arg"
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols="$arg"
+	  if test ! -f "$arg"; then
+	    $echo "$modename: symbol file \`$arg' does not exist"
+	    exit 1
+	  fi
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	inst_prefix)
+	  inst_prefix_dir="$arg"
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release="-$arg"
+	  prev=
+	  continue
+	  ;;
+	objectlist)
+	  if test -f "$arg"; then
+	    save_arg=$arg
+	    moreargs=
+	    for fil in `cat $save_arg`
+	    do
+#	      moreargs="$moreargs $fil"
+	      arg=$fil
+	      # A libtool-controlled object.
+
+	      # Check to see that this really is a libtool object.
+	      if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+		pic_object=
+		non_pic_object=
+
+		# Read the .lo file
+		# If there is no directory component, then add one.
+		case $arg in
+		*/* | *\\*) . $arg ;;
+		*) . ./$arg ;;
+		esac
+
+		if test -z "$pic_object" || \
+		   test -z "$non_pic_object" ||
+		   test "$pic_object" = none && \
+		   test "$non_pic_object" = none; then
+		  $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+		  exit 1
+		fi
+
+		# Extract subdirectory from the argument.
+		xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+		if test "X$xdir" = "X$arg"; then
+		  xdir=
+		else
+		  xdir="$xdir/"
+		fi
+
+		if test "$pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  pic_object="$xdir$pic_object"
+
+		  if test "$prev" = dlfiles; then
+		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		      dlfiles="$dlfiles $pic_object"
+		      prev=
+		      continue
+		    else
+		      # If libtool objects are unsupported, then we need to preload.
+		      prev=dlprefiles
+		    fi
+		  fi
+
+		  # CHECK ME:  I think I busted this.  -Ossama
+		  if test "$prev" = dlprefiles; then
+		    # Preload the old-style object.
+		    dlprefiles="$dlprefiles $pic_object"
+		    prev=
+		  fi
+
+		  # A PIC object.
+		  libobjs="$libobjs $pic_object"
+		  arg="$pic_object"
+		fi
+
+		# Non-PIC object.
+		if test "$non_pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  non_pic_object="$xdir$non_pic_object"
+
+		  # A standard non-PIC object
+		  non_pic_objects="$non_pic_objects $non_pic_object"
+		  if test -z "$pic_object" || test "$pic_object" = none ; then
+		    arg="$non_pic_object"
+		  fi
+		fi
+	      else
+		# Only an error if not doing a dry-run.
+		if test -z "$run"; then
+		  $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+		  exit 1
+		else
+		  # Dry-run case.
+
+		  # Extract subdirectory from the argument.
+		  xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+		  if test "X$xdir" = "X$arg"; then
+		    xdir=
+		  else
+		    xdir="$xdir/"
+		  fi
+
+		  pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+		  non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+		  libobjs="$libobjs $pic_object"
+		  non_pic_objects="$non_pic_objects $non_pic_object"
+		fi
+	      fi
+	    done
+	  else
+	    $echo "$modename: link input file \`$save_arg' does not exist"
+	    exit 1
+	  fi
+	  arg=$save_arg
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case $arg in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    $echo "$modename: only absolute run-paths are allowed" 1>&2
+	    exit 1
+	    ;;
+	  esac
+	  if test "$prev" = rpath; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) rpath="$rpath $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) xrpath="$xrpath $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	xcompiler)
+	  compiler_flags="$compiler_flags $qarg"
+	  prev=
+	  compile_command="$compile_command $qarg"
+	  finalize_command="$finalize_command $qarg"
+	  continue
+	  ;;
+	xlinker)
+	  linker_flags="$linker_flags $qarg"
+	  compiler_flags="$compiler_flags $wl$qarg"
+	  prev=
+	  compile_command="$compile_command $wl$qarg"
+	  finalize_command="$finalize_command $wl$qarg"
+	  continue
+	  ;;
+	xcclinker)
+	  linker_flags="$linker_flags $qarg"
+	  compiler_flags="$compiler_flags $qarg"
+	  prev=
+	  compile_command="$compile_command $qarg"
+	  finalize_command="$finalize_command $qarg"
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi # test -n "$prev"
+
+      prevarg="$arg"
+
+      case $arg in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  compile_command="$compile_command $link_static_flag"
+	  finalize_command="$finalize_command $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	$echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+	continue
+	;;
+
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
+
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
+
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
+
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
+
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  $echo "$modename: more than one -exported-symbols argument is not allowed"
+	  exit 1
+	fi
+	if test "X$arg" = "X-export-symbols"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      -inst-prefix-dir)
+	prev=inst_prefix
+	continue
+	;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+	case $with_gcc/$host in
+	no/*-*-irix* | /*-*-irix*)
+	  compile_command="$compile_command $arg"
+	  finalize_command="$finalize_command $arg"
+	  ;;
+	esac
+	continue
+	;;
+
+      -L*)
+	dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  if test -z "$absdir"; then
+	    $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+	    exit 1
+	  fi
+	  dir="$absdir"
+	  ;;
+	esac
+	case "$deplibs " in
+	*" -L$dir "*) ;;
+	*)
+	  deplibs="$deplibs -L$dir"
+	  lib_search_path="$lib_search_path $dir"
+	  ;;
+	esac
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+	  case :$dllsearchpath: in
+	  *":$dir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$dir";;
+	  esac
+	  ;;
+	esac
+	continue
+	;;
+
+      -l*)
+	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+	  case $host in
+	  *-*-cygwin* | *-*-pw32* | *-*-beos*)
+	    # These systems don't actually have a C or math library (as such)
+	    continue
+	    ;;
+	  *-*-freebsd*-gnu*)
+	    # prevent being parsed by the freebsd regexp below
+	    ;;
+	  *-*-mingw* | *-*-os2*)
+	    # These systems don't actually have a C library (as such)
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-openbsd* | *-*-freebsd*)
+	    # Do not include libc due to us having libc/libc_r.
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C and math libraries are in the System framework
+	    deplibs="$deplibs -framework System"
+	    continue
+	  esac
+	elif test "X$arg" = "X-lc_r"; then
+	 case $host in
+	 *-*-freebsd*-gnu*)
+	   # prevent being parsed by the freebsd regexp below
+	   ;;
+	 *-*-openbsd*)
+	   # Do not include libc_r directly, use -pthread flag.
+	   continue
+	   ;;
+	 esac
+	fi
+	deplibs="$deplibs $arg"
+	continue
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      # gcc -m* arguments should be passed to the linker via $compiler_flags
+      # in order to pass architecture information to the linker
+      # (e.g. 32 vs 64-bit).  This may also be accomplished via -Wl,-mfoo
+      # but this is not reliable with gcc because gcc may use -mfoo to
+      # select a different linker, different libraries, etc, while
+      # -Wl,-mfoo simply passes -mfoo to the linker.
+      -m*)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case $arg in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+        compile_command="$compile_command $arg"
+        finalize_command="$finalize_command $arg"
+        if test "$with_gcc" = "yes" ; then
+          compiler_flags="$compiler_flags $arg"
+        fi
+        continue
+        ;;
+
+      -shrext)
+	prev=shrext
+	continue
+	;;
+
+      -no-fast-install)
+	fast_install=no
+	continue
+	;;
+
+      -no-install)
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+	  # The PATH hackery in wrapper scripts is required on Windows
+	  # in order for the loader to find any dlls it needs.
+	  $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
+	  $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
+	  fast_install=no
+	  ;;
+	*) no_install=yes ;;
+	esac
+	continue
+	;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -objectlist)
+	prev=objectlist
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+	prev=rpath
+	continue
+	;;
+
+      -R)
+	prev=xrpath
+	continue
+	;;
+
+      -R*)
+	dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  $echo "$modename: only absolute run-paths are allowed" 1>&2
+	  exit 1
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) xrpath="$xrpath $dir" ;;
+	esac
+	continue
+	;;
+
+      -static)
+	# The effects of -static are defined in a previous loop.
+	# We used to do the same as -all-static on platforms that
+	# didn't have a PIC flag, but the assumption that the effects
+	# would be equivalent was wrong.  It would break on at least
+	# Digital Unix and AIX.
+	continue
+	;;
+
+      -thread-safe)
+	thread_safe=yes
+	continue
+	;;
+
+      -version-info)
+	prev=vinfo
+	continue
+	;;
+      -version-number)
+	prev=vinfo
+	vinfo_number=yes
+	continue
+	;;
+
+      -Wc,*)
+	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+	  case $flag in
+	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	    flag="\"$flag\""
+	    ;;
+	  esac
+	  arg="$arg $wl$flag"
+	  compiler_flags="$compiler_flags $flag"
+	done
+	IFS="$save_ifs"
+	arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+	;;
+
+      -Wl,*)
+	args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+	  case $flag in
+	    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	    flag="\"$flag\""
+	    ;;
+	  esac
+	  arg="$arg $wl$flag"
+	  compiler_flags="$compiler_flags $wl$flag"
+	  linker_flags="$linker_flags $flag"
+	done
+	IFS="$save_ifs"
+	arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+	;;
+
+      -Xcompiler)
+	prev=xcompiler
+	continue
+	;;
+
+      -Xlinker)
+	prev=xlinker
+	continue
+	;;
+
+      -XCClinker)
+	prev=xcclinker
+	continue
+	;;
+
+      # Some other compiler flag.
+      -* | +*)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case $arg in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+	add_flags="$add_flags $arg"
+	;;
+
+      *.$objext)
+	# A standard object.
+	objs="$objs $arg"
+	;;
+
+      *.lo)
+	# A libtool-controlled object.
+
+	# Check to see that this really is a libtool object.
+	if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  pic_object=
+	  non_pic_object=
+
+	  # Read the .lo file
+	  # If there is no directory component, then add one.
+	  case $arg in
+	  */* | *\\*) . $arg ;;
+	  *) . ./$arg ;;
+	  esac
+
+	  if test -z "$pic_object" || \
+	     test -z "$non_pic_object" ||
+	     test "$pic_object" = none && \
+	     test "$non_pic_object" = none; then
+	    $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+	    exit 1
+	  fi
+
+	  # Extract subdirectory from the argument.
+	  xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+	  if test "X$xdir" = "X$arg"; then
+	    xdir=
+ 	  else
+	    xdir="$xdir/"
+	  fi
+
+	  if test "$pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    pic_object="$xdir$pic_object"
+
+	    if test "$prev" = dlfiles; then
+	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		dlfiles="$dlfiles $pic_object"
+		prev=
+		continue
+	      else
+		# If libtool objects are unsupported, then we need to preload.
+		prev=dlprefiles
+	      fi
+	    fi
+
+	    # CHECK ME:  I think I busted this.  -Ossama
+	    if test "$prev" = dlprefiles; then
+	      # Preload the old-style object.
+	      dlprefiles="$dlprefiles $pic_object"
+	      prev=
+	    fi
+
+	    # A PIC object.
+	    libobjs="$libobjs $pic_object"
+	    arg="$pic_object"
+	  fi
+
+	  # Non-PIC object.
+	  if test "$non_pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    non_pic_object="$xdir$non_pic_object"
+
+	    # A standard non-PIC object
+	    non_pic_objects="$non_pic_objects $non_pic_object"
+	    if test -z "$pic_object" || test "$pic_object" = none ; then
+	      arg="$non_pic_object"
+	    fi
+	  fi
+	else
+	  # Only an error if not doing a dry-run.
+	  if test -z "$run"; then
+	    $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+	    exit 1
+	  else
+	    # Dry-run case.
+
+	    # Extract subdirectory from the argument.
+	    xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+	    if test "X$xdir" = "X$arg"; then
+	      xdir=
+	    else
+	      xdir="$xdir/"
+	    fi
+
+	    pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+	    non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+	    libobjs="$libobjs $pic_object"
+	    non_pic_objects="$non_pic_objects $non_pic_object"
+	  fi
+	fi
+	;;
+
+      *.$libext)
+	# An archive.
+	deplibs="$deplibs $arg"
+	old_deplibs="$old_deplibs $arg"
+	continue
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	if test "$prev" = dlfiles; then
+	  # This library was specified with -dlopen.
+	  dlfiles="$dlfiles $arg"
+	  prev=
+	elif test "$prev" = dlprefiles; then
+	  # The library was specified with -dlpreopen.
+	  dlprefiles="$dlprefiles $arg"
+	  prev=
+	else
+	  deplibs="$deplibs $arg"
+	fi
+	continue
+	;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+	case $arg in
+	*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+	  arg="\"$arg\""
+	  ;;
+	esac
+	add_flags="$add_flags $arg"
+	;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	compile_command="$compile_command $arg"
+	finalize_command="$finalize_command $arg"
+      fi
+    done # argument parsing loop
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Infer tagged configuration to use if any are available and
+    # if one wasn't chosen via the "--tag" command line option.
+    # Only attempt this if the compiler in the base link
+    # command doesn't match the default compiler.
+    if test -n "$available_tags" && test -z "$tagname"; then
+      case $base_compile in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+	for z in $available_tags; do
+	  if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$0" > /dev/null; then
+	    # Evaluate the configuration.
+	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $0`"
+	    case $base_compile in
+	    "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*)
+	      # The compiler in $compile_command matches
+	      # the one in the tagged configuration.
+	      # Assume this is the tagged configuration we want.
+	      tagname=$z
+	      break
+	      ;;
+	    esac
+	  fi
+	done
+	# If $tagname still isn't set, then no tagged configuration
+	# was found and let the user know that the "--tag" command
+	# line option must be used.
+	if test -z "$tagname"; then
+	  $echo "$modename: unable to infer tagged configuration"
+	  $echo "$modename: specify a tag with \`--tag'" 1>&2
+	  exit 1
+#       else
+#         $echo "$modename: using $tagname tagged configuration"
+	fi
+	;;
+      esac
+    fi
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      compile_command="$compile_command $arg"
+      finalize_command="$finalize_command $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+    if test "X$output_objdir" = "X$output"; then
+      output_objdir="$objdir"
+    else
+      output_objdir="$output_objdir/$objdir"
+    fi
+    # Create the object directory.
+    if test ! -d "$output_objdir"; then
+      $show "$mkdir $output_objdir"
+      $run $mkdir $output_objdir
+      status=$?
+      if test "$status" -ne 0 && test ! -d "$output_objdir"; then
+	exit $status
+      fi
+    fi
+
+    # Determine the type of output
+    case $output in
+    "")
+      $echo "$modename: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    case $host in
+    *cygwin* | *mingw* | *pw32*)
+      # don't eliminate duplcations in $postdeps and $predeps
+      duplicate_compiler_generated_deps=yes
+      ;;
+    *)
+      duplicate_compiler_generated_deps=$duplicate_deps
+      ;;
+    esac
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if test "X$duplicate_deps" = "Xyes" ; then
+	case "$libs " in
+	*" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	esac
+      fi
+      libs="$libs $deplib"
+    done
+
+    if test "$linkmode" = lib; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then
+	for pre_post_dep in $predeps $postdeps; do
+	  case "$pre_post_deps " in
+	  *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+	  esac
+	  pre_post_deps="$pre_post_deps $pre_post_dep"
+	done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    notinst_path= # paths that contain not-installed libtool libraries
+    case $linkmode in
+    lib)
+	passes="conv link"
+	for file in $dlfiles $dlprefiles; do
+	  case $file in
+	  *.la) ;;
+	  *)
+	    $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
+	    exit 1
+	    ;;
+	  esac
+	done
+	;;
+    prog)
+	compile_deplibs=
+	finalize_deplibs=
+	alldeplibs=no
+	newdlfiles=
+	newdlprefiles=
+	passes="conv scan dlopen dlpreopen link"
+	;;
+    *)  passes="conv"
+	;;
+    esac
+    for pass in $passes; do
+      if test "$linkmode,$pass" = "lib,link" ||
+	 test "$linkmode,$pass" = "prog,scan"; then
+	libs="$deplibs"
+	deplibs=
+      fi
+      if test "$linkmode" = prog; then
+	case $pass in
+	dlopen) libs="$dlfiles" ;;
+	dlpreopen) libs="$dlprefiles" ;;
+	link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+	esac
+      fi
+      if test "$pass" = dlopen; then
+	# Collect dlpreopened libraries
+	save_deplibs="$deplibs"
+	deplibs=
+      fi
+      for deplib in $libs; do
+	lib=
+	found=no
+	case $deplib in
+	-l*)
+	  if test "$linkmode" != lib && test "$linkmode" != prog; then
+	    $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2
+	    continue
+	  fi
+	  if test "$pass" = conv && test "$allow_undefined" = yes; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
+	  for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do
+	    for search_ext in .la $shrext .so .a; do
+	      # Search the libtool library
+	      lib="$searchdir/lib${name}${search_ext}"
+	      if test -f "$lib"; then
+		if test "$search_ext" = ".la"; then
+		  found=yes
+		else
+		  found=no
+		fi
+		break 2
+	      fi
+	    done
+	  done
+	  if test "$found" != yes; then
+	    # deplib doesn't seem to be a libtool library
+	    if test "$linkmode,$pass" = "prog,link"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  else # deplib is a libtool library
+	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+	    # We need to do some special things here, and not later.
+	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	      case " $predeps $postdeps " in
+	      *" $deplib "*)
+		if (${SED} -e '2q' $lib |
+                    grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+		  library_names=
+		  old_library=
+		  case $lib in
+		  */* | *\\*) . $lib ;;
+		  *) . ./$lib ;;
+		  esac
+		  for l in $old_library $library_names; do
+		    ll="$l"
+		  done
+		  if test "X$ll" = "X$old_library" ; then # only static version available
+		    found=no
+		    ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+		    test "X$ladir" = "X$lib" && ladir="."
+		    lib=$ladir/$old_library
+		    if test "$linkmode,$pass" = "prog,link"; then
+		      compile_deplibs="$deplib $compile_deplibs"
+		      finalize_deplibs="$deplib $finalize_deplibs"
+		    else
+		      deplibs="$deplib $deplibs"
+		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+		    fi
+		    continue
+		  fi
+		fi
+	        ;;
+	      *) ;;
+	      esac
+	    fi
+	  fi
+	  ;; # -l
+	-L*)
+	  case $linkmode in
+	  lib)
+	    deplibs="$deplib $deplibs"
+	    test "$pass" = conv && continue
+	    newdependency_libs="$deplib $newdependency_libs"
+	    newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+	    ;;
+	  prog)
+	    if test "$pass" = conv; then
+	      deplibs="$deplib $deplibs"
+	      continue
+	    fi
+	    if test "$pass" = scan; then
+	      deplibs="$deplib $deplibs"
+	      newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    ;;
+	  *)
+	    $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2
+	    ;;
+	  esac # linkmode
+	  continue
+	  ;; # -L
+	-R*)
+	  if test "$pass" = link; then
+	    dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+	    # Make sure the xrpath contains only unique directories.
+	    case "$xrpath " in
+	    *" $dir "*) ;;
+	    *) xrpath="$xrpath $dir" ;;
+	    esac
+	  fi
+	  deplibs="$deplib $deplibs"
+	  continue
+	  ;;
+	*.la) lib="$deplib" ;;
+	*.$libext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  case $linkmode in
+	  lib)
+	    if test "$deplibs_check_method" != pass_all; then
+	      $echo
+	      $echo "*** Warning: Trying to link with static lib archive $deplib."
+	      $echo "*** I have the capability to make that library automatically link in when"
+	      $echo "*** you link to this library.  But I can only do this if you have a"
+	      $echo "*** shared version of the library, which you do not appear to have"
+	      $echo "*** because the file extensions .$libext of this argument makes me believe"
+	      $echo "*** that it is just a static archive that I should not used here."
+	    else
+	      $echo
+	      $echo "*** Warning: Linking the shared library $output against the"
+	      $echo "*** static library $deplib is not portable!"
+	      deplibs="$deplib $deplibs"
+	    fi
+	    continue
+	    ;;
+	  prog)
+	    if test "$pass" != link; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    continue
+	    ;;
+	  esac # linkmode
+	  ;; # *.$libext
+	*.lo | *.$objext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	  elif test "$linkmode" = prog; then
+	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+	      # If there is no dlopen support or we're linking statically,
+	      # we need to preload.
+	      newdlprefiles="$newdlprefiles $deplib"
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      newdlfiles="$newdlfiles $deplib"
+	    fi
+	  fi
+	  continue
+	  ;;
+	%DEPLIBS%)
+	  alldeplibs=yes
+	  continue
+	  ;;
+	esac # case $deplib
+	if test "$found" = yes || test -f "$lib"; then :
+	else
+	  $echo "$modename: cannot find the library \`$lib'" 1>&2
+	  exit 1
+	fi
+
+	# Check to see that this really is a libtool archive.
+	if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+	  exit 1
+	fi
+
+	ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$ladir" = "X$lib" && ladir="."
+
+	dlname=
+	dlopen=
+	dlpreopen=
+	libdir=
+	library_names=
+	old_library=
+	# If the library was installed with an old release of libtool,
+	# it will not redefine variables installed, or shouldnotlink
+	installed=yes
+	shouldnotlink=no
+
+	# Read the .la file
+	case $lib in
+	*/* | *\\*) . $lib ;;
+	*) . ./$lib ;;
+	esac
+
+	if test "$linkmode,$pass" = "lib,link" ||
+	   test "$linkmode,$pass" = "prog,scan" ||
+	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+	  test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+	  test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+	fi
+
+	if test "$pass" = conv; then
+	  # Only check for convenience libraries
+	  deplibs="$lib $deplibs"
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    #echo "Adding $deplib to \$deplibs"
+	    deplibs="$deplib $deplibs"
+            if test "X$duplicate_deps" = "Xyes" ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	      esac
+            fi
+	    tmp_libs="$tmp_libs $deplib"
+	  done
+	  if test -z "$libdir"; then
+	    if test -z "$old_library"; then
+	      $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+	      exit 1
+	    fi
+	    # It is a libtool convenience library, so add in its objects.
+	    convenience="$convenience $ladir/$objdir/$old_library"
+	    old_convenience="$old_convenience $ladir/$objdir/$old_library"
+	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
+	    $echo "$modename: \`$lib' is not a convenience library" 1>&2
+	    exit 1
+	  fi
+	  continue
+	fi # $pass = conv
+
+    
+	# Get the name of the library we link against.
+	linklib=
+	for l in $old_library $library_names; do
+	  linklib="$l"
+	done
+	if test -z "$linklib"; then
+	  $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+	  exit 1
+	fi
+
+	# This library was specified with -dlopen.
+	if test "$pass" = dlopen; then
+	  if test -z "$libdir"; then
+	    $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
+	    exit 1
+	  fi
+	  if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+	    # If there is no dlname, no dlopen support or we're linking
+	    # statically, we need to preload.  We also need to preload any
+	    # dependent libraries so libltdl's deplib preloader doesn't
+	    # bomb out in the load deplibs phase.
+	    dlprefiles="$dlprefiles $lib $dependency_libs"
+	  else
+	    newdlfiles="$newdlfiles $lib"
+	  fi
+	  continue
+	fi # $pass = dlopen
+
+	# We need an absolute path.
+	case $ladir in
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+	*)
+	  abs_ladir=`cd "$ladir" && pwd`
+	  if test -z "$abs_ladir"; then
+	    $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2
+	    $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+	    abs_ladir="$ladir"
+	  fi
+	  ;;
+	esac
+	laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+
+	# Find the relevant object directory and library name.
+	if test "X$installed" = Xyes; then
+	  if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    $echo "$modename: warning: library \`$lib' was moved." 1>&2
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    libdir="$abs_ladir"
+	  else
+	    dir="$libdir"
+	    absdir="$libdir"
+	  fi
+	else
+	  dir="$ladir/$objdir"
+	  absdir="$abs_ladir/$objdir"
+	  # Remove this search path later
+	  notinst_path="$notinst_path $abs_ladir"
+	fi # $installed = yes
+	name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+
+	# This library was specified with -dlpreopen.
+	if test "$pass" = dlpreopen; then
+	  if test -z "$libdir"; then
+	    $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
+	    exit 1
+	  fi
+	  # Prefer using a static library (so that no silly _DYNAMIC symbols
+	  # are required to link).
+	  if test -n "$old_library"; then
+	    newdlprefiles="$newdlprefiles $dir/$old_library"
+	  # Otherwise, use the dlname, so that lt_dlopen finds it.
+	  elif test -n "$dlname"; then
+	    newdlprefiles="$newdlprefiles $dir/$dlname"
+	  else
+	    newdlprefiles="$newdlprefiles $dir/$linklib"
+	  fi
+	fi # $pass = dlpreopen
+
+	if test -z "$libdir"; then
+	  # Link the convenience library
+	  if test "$linkmode" = lib; then
+	    deplibs="$dir/$old_library $deplibs"
+	  elif test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$dir/$old_library $compile_deplibs"
+	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
+	  else
+	    deplibs="$lib $deplibs" # used for prog,scan pass
+	  fi
+	  continue
+	fi
+
+    
+	if test "$linkmode" = prog && test "$pass" != link; then
+	  newlib_search_path="$newlib_search_path $ladir"
+	  deplibs="$lib $deplibs"
+
+	  linkalldeplibs=no
+	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
+	     test "$build_libtool_libs" = no; then
+	    linkalldeplibs=yes
+	  fi
+
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    case $deplib in
+	    -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
+	    esac
+	    # Need to link against all dependency_libs?
+	    if test "$linkalldeplibs" = yes; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      # Need to hardcode shared library paths
+	      # or/and link against static libraries
+	      newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    if test "X$duplicate_deps" = "Xyes" ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	      esac
+	    fi
+	    tmp_libs="$tmp_libs $deplib"
+	  done # for deplib
+	  continue
+	fi # $linkmode = prog...
+
+	if test "$linkmode,$pass" = "prog,link"; then
+	  if test -n "$library_names" &&
+	     { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+	    # We need to hardcode the library path
+	    if test -n "$shlibpath_var"; then
+	      # Make sure the rpath contains only unique directories.
+	      case "$temp_rpath " in
+	      *" $dir "*) ;;
+	      *" $absdir "*) ;;
+	      *) temp_rpath="$temp_rpath $dir" ;;
+	      esac
+	    fi
+
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) compile_rpath="$compile_rpath $absdir"
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) finalize_rpath="$finalize_rpath $libdir"
+	      esac
+	      ;;
+	    esac
+	  fi # $linkmode,$pass = prog,link...
+
+	  if test "$alldeplibs" = yes &&
+	     { test "$deplibs_check_method" = pass_all ||
+	       { test "$build_libtool_libs" = yes &&
+		 test -n "$library_names"; }; }; then
+	    # We only need to search for static libraries
+	    continue
+	  fi
+	fi
+
+	link_static=no # Whether the deplib will be linked statically
+	if test -n "$library_names" &&
+	   { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+	  if test "$installed" = no; then
+	    notinst_deplibs="$notinst_deplibs $lib"
+	    need_relink=yes
+	  fi
+	  # This is a shared library
+	
+      # Warn about portability, can't link against -module's on some systems (darwin)
+      if test "$shouldnotlink" = yes && test "$pass" = link ; then
+	    $echo
+	    if test "$linkmode" = prog; then
+	      $echo "*** Warning: Linking the executable $output against the loadable module"
+	    else
+	      $echo "*** Warning: Linking the shared library $output against the loadable module"
+	    fi
+	    $echo "*** $linklib is not portable!"    
+      fi	  
+	  if test "$linkmode" = lib &&
+	     test "$hardcode_into_libs" = yes; then
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) compile_rpath="$compile_rpath $absdir"
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) finalize_rpath="$finalize_rpath $libdir"
+	      esac
+	      ;;
+	    esac
+	  fi
+
+	  if test -n "$old_archive_from_expsyms_cmds"; then
+	    # figure out the soname
+	    set dummy $library_names
+	    realname="$2"
+	    shift; shift
+	    libname=`eval \\$echo \"$libname_spec\"`
+	    # use dlname if we got it. it's perfectly good, no?
+	    if test -n "$dlname"; then
+	      soname="$dlname"
+	    elif test -n "$soname_spec"; then
+	      # bleh windows
+	      case $host in
+	      *cygwin* | mingw*)
+		major=`expr $current - $age`
+		versuffix="-$major"
+		;;
+	      esac
+	      eval soname=\"$soname_spec\"
+	    else
+	      soname="$realname"
+	    fi
+
+	    # Make a new name for the extract_expsyms_cmds to use
+	    soroot="$soname"
+	    soname=`$echo $soroot | ${SED} -e 's/^.*\///'`
+	    newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a"
+
+	    # If the library has no export list, then create one now
+	    if test -f "$output_objdir/$soname-def"; then :
+	    else
+	      $show "extracting exported symbol list from \`$soname'"
+	      save_ifs="$IFS"; IFS='~'
+	      eval cmds=\"$extract_expsyms_cmds\"
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		$show "$cmd"
+		$run eval "$cmd" || exit $?
+	      done
+	      IFS="$save_ifs"
+	    fi
+
+	    # Create $newlib
+	    if test -f "$output_objdir/$newlib"; then :; else
+	      $show "generating import library for \`$soname'"
+	      save_ifs="$IFS"; IFS='~'
+	      eval cmds=\"$old_archive_from_expsyms_cmds\"
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		$show "$cmd"
+		$run eval "$cmd" || exit $?
+	      done
+	      IFS="$save_ifs"
+	    fi
+	    # make sure the library variables are pointing to the new library
+	    dir=$output_objdir
+	    linklib=$newlib
+	  fi # test -n "$old_archive_from_expsyms_cmds"
+
+	  if test "$linkmode" = prog || test "$mode" != relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    lib_linked=yes
+	    case $hardcode_action in
+	    immediate | unsupported)
+	      if test "$hardcode_direct" = no; then
+		add="$dir/$linklib"
+		case $host in
+		  *-*-sco3.2v5* ) add_dir="-L$dir" ;;
+		  *-*-darwin* )
+		    # if the lib is a module then we can not link against it, someone
+		    # is ignoring the new warnings I added
+		    if /usr/bin/file -L $add 2> /dev/null | grep "bundle" >/dev/null ; then
+		      $echo "** Warning, lib $linklib is a module, not a shared library"
+		      if test -z "$old_library" ; then
+		        $echo
+		        $echo "** And there doesn't seem to be a static archive available"
+		        $echo "** The link will probably fail, sorry"
+		      else
+		        add="$dir/$old_library"
+		      fi 
+		    fi
+		esac
+	      elif test "$hardcode_minus_L" = no; then
+		case $host in
+		*-*-sunos*) add_shlibpath="$dir" ;;
+		esac
+		add_dir="-L$dir"
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = no; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    relink)
+	      if test "$hardcode_direct" = yes; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = yes; then
+		add_dir="-L$dir"
+		# Try looking first in the location we're being installed to.
+		if test -n "$inst_prefix_dir"; then
+		  case "$libdir" in
+		    [\\/]*)
+		      add_dir="-L$inst_prefix_dir$libdir $add_dir"
+		      ;;
+		  esac
+		fi
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = yes; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    *) lib_linked=no ;;
+	    esac
+
+	    if test "$lib_linked" != yes; then
+	      $echo "$modename: configuration error: unsupported hardcode properties"
+	      exit 1
+	    fi
+
+	    if test -n "$add_shlibpath"; then
+	      case :$compile_shlibpath: in
+	      *":$add_shlibpath:"*) ;;
+	      *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+	      esac
+	    fi
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	      if test "$hardcode_direct" != yes && \
+		 test "$hardcode_minus_L" != yes && \
+		 test "$hardcode_shlibpath_var" = yes; then
+		case :$finalize_shlibpath: in
+		*":$libdir:"*) ;;
+		*) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+		esac
+	      fi
+	    fi
+	  fi
+
+	  if test "$linkmode" = prog || test "$mode" = relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    # Finalize command for both is simple: just hardcode it.
+	    if test "$hardcode_direct" = yes; then
+	      add="$libdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      add_dir="-L$libdir"
+	      add="-l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
+	      case :$finalize_shlibpath: in
+	      *":$libdir:"*) ;;
+	      *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+	      esac
+	      add="-l$name"
+	    elif test "$hardcode_automatic" = yes; then
+	      if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then
+	        add="$inst_prefix_dir$libdir/$linklib"
+	      else
+	        add="$libdir/$linklib"
+	      fi
+	    else
+	      # We cannot seem to hardcode it, guess we'll fake it.
+	      add_dir="-L$libdir"
+	      # Try looking first in the location we're being installed to.
+	      if test -n "$inst_prefix_dir"; then
+		case "$libdir" in
+		  [\\/]*)
+		    add_dir="-L$inst_prefix_dir$libdir $add_dir"
+		    ;;
+		esac
+	      fi
+	      add="-l$name"
+	    fi
+
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	    fi
+	  fi
+	elif test "$linkmode" = prog; then
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
+	    compile_deplibs="$dir/$linklib $compile_deplibs"
+	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
+	  else
+	    compile_deplibs="-l$name -L$dir $compile_deplibs"
+	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+	  fi
+	elif test "$build_libtool_libs" = yes; then
+	  # Not a shared library
+	  if test "$deplibs_check_method" != pass_all; then
+	    # We're trying link a shared library against a static one
+	    # but the system doesn't support it.
+
+	    # Just print a warning and add the library to dependency_libs so
+	    # that the program can be linked against the static library.
+	    $echo
+	    $echo "*** Warning: This system can not link to static lib archive $lib."
+	    $echo "*** I have the capability to make that library automatically link in when"
+	    $echo "*** you link to this library.  But I can only do this if you have a"
+	    $echo "*** shared version of the library, which you do not appear to have."
+	    if test "$module" = yes; then
+	      $echo "*** But as you try to build a module library, libtool will still create "
+	      $echo "*** a static module, that should work as long as the dlopening application"
+	      $echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+	      if test -z "$global_symbol_pipe"; then
+		$echo
+		$echo "*** However, this would only work if libtool was able to extract symbol"
+		$echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+		$echo "*** not find such a program.  So, this module is probably useless."
+		$echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	      fi
+	      if test "$build_old_libs" = no; then
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  else
+	    convenience="$convenience $dir/$old_library"
+	    old_convenience="$old_convenience $dir/$old_library"
+	    deplibs="$dir/$old_library $deplibs"
+	    link_static=yes
+	  fi
+	fi # link shared/static library?
+
+	if test "$linkmode" = lib; then
+	  #if test -n "$dependency_libs" &&
+	  #   { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes ||
+	  #     test "$link_static" = yes; }; then
+	    # Extract -R from dependency_libs
+	    temp_deplibs=
+	    for libdir in $dependency_libs; do
+	      case $libdir in
+	      -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'`
+		   case " $xrpath " in
+		   *" $temp_xrpath "*) ;;
+		   *) xrpath="$xrpath $temp_xrpath";;
+		   esac;;
+	      *) temp_deplibs="$temp_deplibs $libdir";;
+	      esac
+	    done
+	    dependency_libs="$temp_deplibs"
+	  #fi
+
+	  newlib_search_path="$newlib_search_path $absdir"
+	  # Link against this library
+	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+	  # ... and its dependency_libs
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    newdependency_libs="$deplib $newdependency_libs"
+	    if test "X$duplicate_deps" = "Xyes" ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	      esac
+	    fi
+	    tmp_libs="$tmp_libs $deplib"
+	  done
+
+	  if test "$link_all_deplibs" != no; then
+	    # Add the search paths of all dependency libraries
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      -L*) path="$deplib" ;;
+	      *.la)
+		dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
+		test "X$dir" = "X$deplib" && dir="."
+		# We need an absolute path.
+		case $dir in
+		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+		*)
+		  absdir=`cd "$dir" && pwd`
+		  if test -z "$absdir"; then
+		    $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+		    absdir="$dir"
+		  fi
+		  ;;
+		esac
+		if grep "^installed=no" $deplib > /dev/null; then
+		  path="$absdir/$objdir"
+		else
+		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  if test -z "$libdir"; then
+		    $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+		    exit 1
+		  fi
+		  if test "$absdir" != "$libdir"; then
+		    # Sure, some shells/systems don't implement the -ef.
+		    # Those will have to live with the warning.
+		    test "$absdir" -ef "$libdir" > /dev/null 2>&1 ||
+		      $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
+		  fi
+		  path="$absdir"
+		fi
+		depdepl=
+		case $host in
+		*-*-darwin*)
+		  # we do not want to link against static libs, but need to link against shared
+		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+		  if test -n "$deplibrary_names" ; then
+		    for tmp in $deplibrary_names ; do
+		      depdepl=$tmp
+		    done
+		    if test -f "$path/$depdepl" ; then
+		      depdepl="$path/$depdepl"
+		   fi
+		    # do not add paths which are already there
+		    case " $newlib_search_path " in
+		    *" $path "*) ;;
+		    *) newlib_search_path="$newlib_search_path $path";;
+		    esac
+		    path=""
+		  fi
+		  ;;
+		*)
+		path="-L$path"
+		;;
+		esac 
+		
+		;;
+		  -l*)
+		case $host in
+		*-*-darwin*)
+		 # Again, we only want to link against shared libraries
+		 eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"`
+		 for tmp in $newlib_search_path ; do
+		     if test -f "$tmp/lib$tmp_libs.dylib" ; then
+		       eval depdepl="$tmp/lib$tmp_libs.dylib"
+		       break
+		     fi  
+         done
+         path=""
+		  ;;
+		*) continue ;;
+		esac  		  
+		;;
+	      *) continue ;;
+	      esac
+	      case " $deplibs " in
+	      *" $depdepl "*) ;;
+	      *) deplibs="$deplibs $depdepl" ;;
+	      esac	      
+	      case " $deplibs " in
+	      *" $path "*) ;;
+	      *) deplibs="$deplibs $path" ;;
+	      esac
+	    done
+	  fi # link_all_deplibs != no
+	fi # linkmode = lib
+      done # for deplib in $libs
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
+	# Link the dlpreopened libraries before other libraries
+	for deplib in $save_deplibs; do
+	  deplibs="$deplib $deplibs"
+	done
+      fi
+      if test "$pass" != dlopen; then
+	if test "$pass" != conv; then
+	  # Make sure lib_search_path contains only unique directories.
+	  lib_search_path=
+	  for dir in $newlib_search_path; do
+	    case "$lib_search_path " in
+	    *" $dir "*) ;;
+	    *) lib_search_path="$lib_search_path $dir" ;;
+	    esac
+	  done
+	  newlib_search_path=
+	fi
+
+	if test "$linkmode,$pass" != "prog,link"; then
+	  vars="deplibs"
+	else
+	  vars="compile_deplibs finalize_deplibs"
+	fi
+	for var in $vars dependency_libs; do
+	  # Add libraries to $var in reverse order
+	  eval tmp_libs=\"\$$var\"
+	  new_libs=
+	  for deplib in $tmp_libs; do
+	    # FIXME: Pedantically, this is the right thing to do, so
+	    #        that some nasty dependency loop isn't accidentally
+	    #        broken:
+	    #new_libs="$deplib $new_libs"
+	    # Pragmatically, this seems to cause very few problems in
+	    # practice:
+	    case $deplib in
+	    -L*) new_libs="$deplib $new_libs" ;;
+	    -R*) ;;
+	    *)
+	      # And here is the reason: when a library appears more
+	      # than once as an explicit dependence of a library, or
+	      # is implicitly linked in more than once by the
+	      # compiler, it is considered special, and multiple
+	      # occurrences thereof are not removed.  Compare this
+	      # with having the same library being listed as a
+	      # dependency of multiple other libraries: in this case,
+	      # we know (pedantically, we assume) the library does not
+	      # need to be listed more than once, so we keep only the
+	      # last copy.  This is not always right, but it is rare
+	      # enough that we require users that really mean to play
+	      # such unportable linking tricks to link the library
+	      # using -Wl,-lname, so that libtool does not consider it
+	      # for duplicate removal.
+	      case " $specialdeplibs " in
+	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
+	      *)
+		case " $new_libs " in
+		*" $deplib "*) ;;
+		*) new_libs="$deplib $new_libs" ;;
+		esac
+		;;
+	      esac
+	      ;;
+	    esac
+	  done
+	  tmp_libs=
+	  for deplib in $new_libs; do
+	    case $deplib in
+	    -L*)
+	      case " $tmp_libs " in
+	      *" $deplib "*) ;;
+	      *) tmp_libs="$tmp_libs $deplib" ;;
+	      esac
+	      ;;
+	    *) tmp_libs="$tmp_libs $deplib" ;;
+	    esac
+	  done
+	  eval $var=\"$tmp_libs\"
+	done # for var
+      fi
+      # Last step: remove runtime libs from dependency_libs (they stay in deplibs)
+      tmp_libs=
+      for i in $dependency_libs ; do
+	case " $predeps $postdeps $compiler_lib_search_path " in
+	*" $i "*)
+	  i=""
+	  ;;
+	esac
+	if test -n "$i" ; then
+	  tmp_libs="$tmp_libs $i"
+	fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
+      dlprefiles="$newdlprefiles"
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$deplibs"; then
+	$echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+	$echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+	$echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	$echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+      fi
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      objs="$objs$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case $outputname in
+      lib*)
+	name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+	eval shared_ext=\"$shrext\"
+	eval libname=\"$libname_spec\"
+	;;
+      *)
+	if test "$module" = no; then
+	  $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	fi
+	if test "$need_lib_prefix" != no; then
+	  # Add the "lib" prefix for modules if required
+	  name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+	  eval shared_ext=\"$shrext\"
+	  eval libname=\"$libname_spec\"
+	else
+	  libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+	fi
+	;;
+      esac
+
+      if test -n "$objs"; then
+	if test "$deplibs_check_method" != pass_all; then
+	  $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
+	  exit 1
+	else
+	  $echo
+	  $echo "*** Warning: Linking the shared library $output against the non-libtool"
+	  $echo "*** objects $objs is not portable!"
+	  libobjs="$libobjs $objs"
+	fi
+      fi
+
+      if test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2
+      fi
+
+      set dummy $rpath
+      if test "$#" -gt 2; then
+	$echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      fi
+      install_libdir="$2"
+
+      oldlibs=
+      if test -z "$rpath"; then
+	if test "$build_libtool_libs" = yes; then
+	  # Building a libtool convenience library.
+	  # Some compilers have problems with a `.al' extension so
+	  # convenience libraries should have the same extension an
+	  # archive normally would.
+	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
+	  build_libtool_libs=convenience
+	  build_old_libs=yes
+	fi
+
+	if test -n "$vinfo"; then
+	  $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2
+	fi
+
+	if test -n "$release"; then
+	  $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+	fi
+      else
+
+	# Parse the version information argument.
+	save_ifs="$IFS"; IFS=':'
+	set dummy $vinfo 0 0 0
+	IFS="$save_ifs"
+
+	if test -n "$8"; then
+	  $echo "$modename: too many parameters to \`-version-info'" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	fi
+
+	# convert absolute version numbers to libtool ages
+	# this retains compatibility with .la files and attempts
+	# to make the code below a bit more comprehensible
+	
+	case $vinfo_number in
+	yes)
+	  number_major="$2"
+	  number_minor="$3"
+	  number_revision="$4"
+	  #
+	  # There are really only two kinds -- those that
+	  # use the current revision as the major version
+	  # and those that subtract age and use age as
+	  # a minor version.  But, then there is irix
+	  # which has an extra 1 added just for fun
+	  #
+	  case $version_type in
+	  darwin|linux|osf|windows)
+	    current=`expr $number_major + $number_minor`
+	    age="$number_minor"
+	    revision="$number_revision"
+	    ;;
+	  freebsd-aout|freebsd-elf|sunos)
+	    current="$number_major"
+	    revision="$number_minor"
+	    age="0"
+	    ;;
+	  irix|nonstopux)
+	    current=`expr $number_major + $number_minor - 1`
+	    age="$number_minor"
+	    revision="$number_minor"
+	    ;;
+	  esac
+	  ;;
+	no)
+	  current="$2"
+	  revision="$3"
+	  age="$4"
+	  ;;
+	esac
+
+	# Check that each of the things are valid numbers.
+	case $current in
+	0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
+	*)
+	  $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	case $revision in
+	0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
+	*)
+	  $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	case $age in
+	0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;;
+	*)
+	  $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	if test "$age" -gt "$current"; then
+	  $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+	  $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+	  exit 1
+	fi
+
+	# Calculate the version variables.
+	major=
+	versuffix=
+	verstring=
+	case $version_type in
+	none) ;;
+
+	darwin)
+	  # Like Linux, but with the current version available in
+	  # verstring for coding it into the library header
+	  major=.`expr $current - $age`
+	  versuffix="$major.$age.$revision"
+	  # Darwin ld doesn't like 0 for these options...
+	  minor_current=`expr $current + 1`
+	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+	  ;;
+
+	freebsd-aout)
+	  major=".$current"
+	  versuffix=".$current.$revision";
+	  ;;
+
+	freebsd-elf)
+	  major=".$current"
+	  versuffix=".$current";
+	  ;;
+
+	irix | nonstopux)
+	  major=`expr $current - $age + 1`
+
+	  case $version_type in
+	    nonstopux) verstring_prefix=nonstopux ;;
+	    *)         verstring_prefix=sgi ;;
+	  esac
+	  verstring="$verstring_prefix$major.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$revision
+	  while test "$loop" -ne 0; do
+	    iface=`expr $revision - $loop`
+	    loop=`expr $loop - 1`
+	    verstring="$verstring_prefix$major.$iface:$verstring"
+	  done
+
+	  # Before this point, $major must not contain `.'.
+	  major=.$major
+	  versuffix="$major.$revision"
+	  ;;
+
+	linux)
+	  major=.`expr $current - $age`
+	  versuffix="$major.$age.$revision"
+	  ;;
+
+	osf)
+	  major=.`expr $current - $age`
+	  versuffix=".$current.$age.$revision"
+	  verstring="$current.$age.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$age
+	  while test "$loop" -ne 0; do
+	    iface=`expr $current - $loop`
+	    loop=`expr $loop - 1`
+	    verstring="$verstring:${iface}.0"
+	  done
+
+	  # Make executables depend on our current version.
+	  verstring="$verstring:${current}.0"
+	  ;;
+
+	sunos)
+	  major=".$current"
+	  versuffix=".$current.$revision"
+	  ;;
+
+	windows)
+	  # Use '-' rather than '.', since we only want one
+	  # extension on DOS 8.3 filesystems.
+	  major=`expr $current - $age`
+	  versuffix="-$major"
+	  ;;
+
+	*)
+	  $echo "$modename: unknown library version type \`$version_type'" 1>&2
+	  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	# Clear the version info if we defaulted, and they specified a release.
+	if test -z "$vinfo" && test -n "$release"; then
+	  major=
+	  case $version_type in
+	  darwin)
+	    # we can't check for "0.0" in archive_cmds due to quoting
+	    # problems, so we reset it completely
+	    verstring=
+	    ;;
+	  *)
+	    verstring="0.0"
+	    ;;
+	  esac
+	  if test "$need_version" = no; then
+	    versuffix=
+	  else
+	    versuffix=".0.0"
+	  fi
+	fi
+
+	# Remove version info from name if versioning should be avoided
+	if test "$avoid_version" = yes && test "$need_version" = no; then
+	  major=
+	  versuffix=
+	  verstring=""
+	fi
+
+	# Check to see if the archive will have undefined symbols.
+	if test "$allow_undefined" = yes; then
+	  if test "$allow_undefined_flag" = unsupported; then
+	    $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+	    build_libtool_libs=no
+	    build_old_libs=yes
+	  fi
+	else
+	  # Don't allow undefined symbols.
+	  allow_undefined_flag="$no_undefined_flag"
+	fi
+      fi
+
+      if test "$mode" != relink; then
+	# Remove our outputs, but don't remove object files since they
+	# may have been created when compiling PIC objects.
+	removelist=
+	tempremovelist=`$echo "$output_objdir/*"`
+	for p in $tempremovelist; do
+	  case $p in
+	    *.$objext)
+	       ;;
+	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+	       removelist="$removelist $p"
+	       ;;
+	    *) ;;
+	  esac
+	done
+	if test -n "$removelist"; then
+	  $show "${rm}r $removelist"
+	  $run ${rm}r $removelist
+	fi
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+	oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+	# Transform .lo files to .o files.
+	oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      for path in $notinst_path; do
+	lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'`
+	deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'`
+	dependency_libs=`$echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'`
+      done
+
+      if test -n "$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	temp_xrpath=
+	for libdir in $xrpath; do
+	  temp_xrpath="$temp_xrpath -R$libdir"
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_rpath="$finalize_rpath $libdir" ;;
+	  esac
+	done
+	if true || test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+	  dependency_libs="$temp_xrpath $dependency_libs"
+	fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles="$dlfiles"
+      dlfiles=
+      for lib in $old_dlfiles; do
+	case " $dlprefiles $dlfiles " in
+	*" $lib "*) ;;
+	*) dlfiles="$dlfiles $lib" ;;
+	esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles="$dlprefiles"
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+	case "$dlprefiles " in
+	*" $lib "*) ;;
+	*) dlprefiles="$dlprefiles $lib" ;;
+	esac
+      done
+
+      if test "$build_libtool_libs" = yes; then
+	if test -n "$rpath"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
+	    # these systems don't actually have a c library (as such)!
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C library is in the System framework
+	    deplibs="$deplibs -framework System"
+	    ;;
+	  *-*-netbsd*)
+	    # Don't link with libc until the a.out ld.so is fixed.
+	    ;;
+	  *-*-freebsd*-gnu*)
+	    # Prevent $arg from being parsed by the freebsd regexp below.
+	    if test "$build_libtool_need_lc" = "yes"; then
+	      deplibs="$deplibs -lc"
+	    fi
+	    ;;
+	  *-*-openbsd* | *-*-freebsd*)
+	    # Do not include libc due to us having libc/libc_r.
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+ 	  *)
+	    # Add libc to deplibs on all other systems if necessary.
+	    if test "$build_libtool_need_lc" = "yes"; then
+	      deplibs="$deplibs -lc"
+	    fi
+	    ;;
+	  esac
+	fi
+
+	# Transform deplibs into only deplibs that can be linked in shared.
+	name_save=$name
+	libname_save=$libname
+	release_save=$release
+	versuffix_save=$versuffix
+	major_save=$major
+	# I'm not sure if I'm treating the release correctly.  I think
+	# release should show up in the -l (ie -lgmp5) so we don't want to
+	# add it in twice.  Is that correct?
+	release=""
+	versuffix=""
+	major=""
+	newdeplibs=
+	droppeddeps=no
+	case $deplibs_check_method in
+	pass_all)
+	  # Don't check for shared/static.  Everything works.
+	  # This might be a little naive.  We might want to check
+	  # whether the library exists or not.  But this is on
+	  # osf3 & osf4 and I'm not really sure... Just
+	  # implementing what was already the behavior.
+	  newdeplibs=$deplibs
+	  ;;
+	test_compile)
+	  # This code stresses the "libraries are programs" paradigm to its
+	  # limits. Maybe even breaks it.  We compile a program, linking it
+	  # against the deplibs as a proxy for the library.  Then we can check
+	  # whether they linked in statically or dynamically with ldd.
+	  $rm conftest.c
+	  cat > conftest.c <<EOF
+	  int main() { return 0; }
+EOF
+	  $rm conftest
+	  $LTCC -o conftest conftest.c $deplibs
+	  if test "$?" -eq 0 ; then
+	    ldd_output=`ldd conftest`
+	    for i in $deplibs; do
+	      name="`expr $i : '-l\(.*\)'`"
+	      # If $name is empty we are operating on a -L argument.
+              if test "$name" != "" && test "$name" -ne "0"; then
+		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		  case " $predeps $postdeps " in
+		  *" $i "*)
+		    newdeplibs="$newdeplibs $i"
+		    i=""
+		    ;;
+		  esac
+	        fi
+		if test -n "$i" ; then
+		  libname=`eval \\$echo \"$libname_spec\"`
+		  deplib_matches=`eval \\$echo \"$library_names_spec\"`
+		  set dummy $deplib_matches
+		  deplib_match=$2
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		    newdeplibs="$newdeplibs $i"
+		  else
+		    droppeddeps=yes
+		    $echo
+		    $echo "*** Warning: dynamic linker does not accept needed library $i."
+		    $echo "*** I have the capability to make that library automatically link in when"
+		    $echo "*** you link to this library.  But I can only do this if you have a"
+		    $echo "*** shared version of the library, which I believe you do not have"
+		    $echo "*** because a test_compile did reveal that the linker did not use it for"
+		    $echo "*** its dynamic dependency list that programs get resolved with at runtime."
+		  fi
+		fi
+	      else
+		newdeplibs="$newdeplibs $i"
+	      fi
+	    done
+	  else
+	    # Error occurred in the first compile.  Let's try to salvage
+	    # the situation: Compile a separate program for each library.
+	    for i in $deplibs; do
+	      name="`expr $i : '-l\(.*\)'`"
+	      # If $name is empty we are operating on a -L argument.
+              if test "$name" != "" && test "$name" != "0"; then
+		$rm conftest
+		$LTCC -o conftest conftest.c $i
+		# Did it work?
+		if test "$?" -eq 0 ; then
+		  ldd_output=`ldd conftest`
+		  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		    case " $predeps $postdeps " in
+		    *" $i "*)
+		      newdeplibs="$newdeplibs $i"
+		      i=""
+		      ;;
+		    esac
+		  fi
+		  if test -n "$i" ; then
+		    libname=`eval \\$echo \"$libname_spec\"`
+		    deplib_matches=`eval \\$echo \"$library_names_spec\"`
+		    set dummy $deplib_matches
+		    deplib_match=$2
+		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		      newdeplibs="$newdeplibs $i"
+		    else
+		      droppeddeps=yes
+		      $echo
+		      $echo "*** Warning: dynamic linker does not accept needed library $i."
+		      $echo "*** I have the capability to make that library automatically link in when"
+		      $echo "*** you link to this library.  But I can only do this if you have a"
+		      $echo "*** shared version of the library, which you do not appear to have"
+		      $echo "*** because a test_compile did reveal that the linker did not use this one"
+		      $echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+		    fi
+		  fi
+		else
+		  droppeddeps=yes
+		  $echo
+		  $echo "*** Warning!  Library $i is needed by this library but I was not able to"
+		  $echo "***  make it link in!  You will probably need to install it or some"
+		  $echo "*** library that it depends on before this library will be fully"
+		  $echo "*** functional.  Installing it before continuing would be even better."
+		fi
+	      else
+		newdeplibs="$newdeplibs $i"
+	      fi
+	    done
+	  fi
+	  ;;
+	file_magic*)
+	  set dummy $deplibs_check_method
+	  file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    name="`expr $a_deplib : '-l\(.*\)'`"
+	    # If $name is empty we are operating on a -L argument.
+            if test "$name" != "" && test  "$name" != "0"; then
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  newdeplibs="$newdeplibs $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval \\$echo \"$libname_spec\"`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		      # Follow soft links.
+		      if ls -lLd "$potent_lib" 2>/dev/null \
+			 | grep " -> " >/dev/null; then
+			continue
+		      fi
+		      # The statement above tries to avoid entering an
+		      # endless loop below, in case of cyclic links.
+		      # We might still enter an endless loop, since a link
+		      # loop can be closed while we follow links,
+		      # but so what?
+		      potlib="$potent_lib"
+		      while test -h "$potlib" 2>/dev/null; do
+			potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+			case $potliblink in
+			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+			*) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+			esac
+		      done
+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+			 | ${SED} 10q \
+			 | $EGREP "$file_magic_regex" > /dev/null; then
+			newdeplibs="$newdeplibs $a_deplib"
+			a_deplib=""
+			break 2
+		      fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		$echo
+		$echo "*** Warning: linker path does not have real file for library $a_deplib."
+		$echo "*** I have the capability to make that library automatically link in when"
+		$echo "*** you link to this library.  But I can only do this if you have a"
+		$echo "*** shared version of the library, which you do not appear to have"
+		$echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $echo "*** with $libname but no candidates were found. (...for file magic test)"
+		else
+		  $echo "*** with $libname and none of the candidates passed a file format test"
+		  $echo "*** using a file magic. Last file checked: $potlib"
+		fi
+	      fi
+	    else
+	      # Add a -L argument.
+	      newdeplibs="$newdeplibs $a_deplib"
+	    fi
+	  done # Gone through all deplibs.
+	  ;;
+	match_pattern*)
+	  set dummy $deplibs_check_method
+	  match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    name="`expr $a_deplib : '-l\(.*\)'`"
+	    # If $name is empty we are operating on a -L argument.
+	    if test -n "$name" && test "$name" != "0"; then
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  newdeplibs="$newdeplibs $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval \\$echo \"$libname_spec\"`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		    potlib="$potent_lib" # see symlink-check above in file_magic test
+		    if eval $echo \"$potent_lib\" 2>/dev/null \
+		        | ${SED} 10q \
+		        | $EGREP "$match_pattern_regex" > /dev/null; then
+		      newdeplibs="$newdeplibs $a_deplib"
+		      a_deplib=""
+		      break 2
+		    fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		$echo
+		$echo "*** Warning: linker path does not have real file for library $a_deplib."
+		$echo "*** I have the capability to make that library automatically link in when"
+		$echo "*** you link to this library.  But I can only do this if you have a"
+		$echo "*** shared version of the library, which you do not appear to have"
+		$echo "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $echo "*** with $libname but no candidates were found. (...for regex pattern test)"
+		else
+		  $echo "*** with $libname and none of the candidates passed a file format test"
+		  $echo "*** using a regex pattern. Last file checked: $potlib"
+		fi
+	      fi
+	    else
+	      # Add a -L argument.
+	      newdeplibs="$newdeplibs $a_deplib"
+	    fi
+	  done # Gone through all deplibs.
+	  ;;
+	none | unknown | *)
+	  newdeplibs=""
+	  tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+	    -e 's/ -[LR][^ ]*//g'`
+	  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	    for i in $predeps $postdeps ; do
+	      # can't use Xsed below, because $i might contain '/'
+	      tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"`
+	    done
+	  fi
+	  if $echo "X $tmp_deplibs" | $Xsed -e 's/[ 	]//g' \
+	    | grep . >/dev/null; then
+	    $echo
+	    if test "X$deplibs_check_method" = "Xnone"; then
+	      $echo "*** Warning: inter-library dependencies are not supported in this platform."
+	    else
+	      $echo "*** Warning: inter-library dependencies are not known to be supported."
+	    fi
+	    $echo "*** All declared inter-library dependencies are being dropped."
+	    droppeddeps=yes
+	  fi
+	  ;;
+	esac
+	versuffix=$versuffix_save
+	major=$major_save
+	release=$release_save
+	libname=$libname_save
+	name=$name_save
+
+	case $host in
+	*-*-rhapsody* | *-*-darwin1.[012])
+	  # On Rhapsody replace the C library is the System framework
+	  newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'`
+	  ;;
+	esac
+
+	if test "$droppeddeps" = yes; then
+	  if test "$module" = yes; then
+	    $echo
+	    $echo "*** Warning: libtool could not satisfy all declared inter-library"
+	    $echo "*** dependencies of module $libname.  Therefore, libtool will create"
+	    $echo "*** a static module, that should work as long as the dlopening"
+	    $echo "*** application is linked with the -dlopen flag."
+	    if test -z "$global_symbol_pipe"; then
+	      $echo
+	      $echo "*** However, this would only work if libtool was able to extract symbol"
+	      $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+	      $echo "*** not find such a program.  So, this module is probably useless."
+	      $echo "*** \`nm' from GNU binutils and a full rebuild may help."
+	    fi
+	    if test "$build_old_libs" = no; then
+	      oldlibs="$output_objdir/$libname.$libext"
+	      build_libtool_libs=module
+	      build_old_libs=yes
+	    else
+	      build_libtool_libs=no
+	    fi
+	  else
+	    $echo "*** The inter-library dependencies that have been dropped here will be"
+	    $echo "*** automatically added whenever a program is linked with this library"
+	    $echo "*** or is declared to -dlopen it."
+
+	    if test "$allow_undefined" = no; then
+	      $echo
+	      $echo "*** Since this library must not contain undefined symbols,"
+	      $echo "*** because either the platform does not support them or"
+	      $echo "*** it was explicitly requested with -no-undefined,"
+	      $echo "*** libtool will only create a static version of it."
+	      if test "$build_old_libs" = no; then
+		oldlibs="$output_objdir/$libname.$libext"
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  fi
+	fi
+	# Done checking deplibs!
+	deplibs=$newdeplibs
+      fi
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+	if test "$hardcode_into_libs" = yes; then
+	  # Hardcode the library paths
+	  hardcode_libdirs=
+	  dep_rpath=
+	  rpath="$finalize_rpath"
+	  test "$mode" != relink && test "$fast_install" = no && rpath="$compile_rpath$rpath"
+	  for libdir in $rpath; do
+	    if test -n "$hardcode_libdir_flag_spec"; then
+	      if test -n "$hardcode_libdir_separator"; then
+		if test -z "$hardcode_libdirs"; then
+		  hardcode_libdirs="$libdir"
+		else
+		  # Just accumulate the unique libdirs.
+		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		    ;;
+		  *)
+		    hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		    ;;
+		  esac
+		fi
+	      else
+		eval flag=\"$hardcode_libdir_flag_spec\"
+		dep_rpath="$dep_rpath $flag"
+	      fi
+	    elif test -n "$runpath_var"; then
+	      case "$perm_rpath " in
+	      *" $libdir "*) ;;
+	      *) perm_rpath="$perm_rpath $libdir" ;;
+	      esac
+	    fi
+	  done
+	  # Substitute the hardcoded libdirs into the rpath.
+	  if test -n "$hardcode_libdir_separator" &&
+	     test -n "$hardcode_libdirs"; then
+	    libdir="$hardcode_libdirs"
+	    if test -n "$hardcode_libdir_flag_spec_ld"; then
+	      eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+	    else
+	      eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+	    fi
+	  fi
+	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
+	    # We should set the runpath_var.
+	    rpath=
+	    for dir in $perm_rpath; do
+	      rpath="$rpath$dir:"
+	    done
+	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+	  fi
+	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+	fi
+
+	shlibpath="$finalize_shlibpath"
+	test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+	if test -n "$shlibpath"; then
+	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+	fi
+
+	# Get the real and link names of the library.
+	eval shared_ext=\"$shrext\"
+	eval library_names=\"$library_names_spec\"
+	set dummy $library_names
+	realname="$2"
+	shift; shift
+
+	if test -n "$soname_spec"; then
+	  eval soname=\"$soname_spec\"
+	else
+	  soname="$realname"
+	fi
+	if test -z "$dlname"; then
+	  dlname=$soname
+	fi
+
+	lib="$output_objdir/$realname"
+	for link
+	do
+	  linknames="$linknames $link"
+	done
+
+	# Use standard objects if they are pic
+	test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+	# Prepare the list of exported symbols
+	if test -z "$export_symbols"; then
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    $show "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $run $rm $export_symbols
+	    eval cmds=\"$export_symbols_cmds\"
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd in $cmds; do
+	      IFS="$save_ifs"
+	      if len=`expr "X$cmd" : ".*"` &&
+	       test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	        $show "$cmd"
+	        $run eval "$cmd" || exit $?
+	        skipped_export=false
+	      else
+	        # The command line is too long to execute in one step.
+	        $show "using reloadable object file for export list..."
+	        skipped_export=:
+	      fi
+	    done
+	    IFS="$save_ifs"
+	    if test -n "$export_symbols_regex"; then
+	      $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+	      $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+	      $run eval '$mv "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+	fi
+
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+	fi
+
+	tmp_deplibs=
+	for test_deplib in $deplibs; do
+		case " $convenience " in
+		*" $test_deplib "*) ;;
+		*) 
+			tmp_deplibs="$tmp_deplibs $test_deplib"
+			;;
+		esac
+	done
+	deplibs="$tmp_deplibs" 
+
+	if test -n "$convenience"; then
+	  if test -n "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	  else
+	    gentop="$output_objdir/${outputname}x"
+	    $show "${rm}r $gentop"
+	    $run ${rm}r "$gentop"
+	    $show "$mkdir $gentop"
+	    $run $mkdir "$gentop"
+	    status=$?
+	    if test "$status" -ne 0 && test ! -d "$gentop"; then
+	      exit $status
+	    fi
+	    generated="$generated $gentop"
+
+	    for xlib in $convenience; do
+	      # Extract the objects.
+	      case $xlib in
+	      [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+	      *) xabs=`pwd`"/$xlib" ;;
+	      esac
+	      xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+	      xdir="$gentop/$xlib"
+
+	      $show "${rm}r $xdir"
+	      $run ${rm}r "$xdir"
+	      $show "$mkdir $xdir"
+	      $run $mkdir "$xdir"
+	      status=$?
+	      if test "$status" -ne 0 && test ! -d "$xdir"; then
+		exit $status
+	      fi
+	      # We will extract separately just the conflicting names and we will no
+	      # longer touch any unique names. It is faster to leave these extract
+	      # automatically by $AR in one run.
+	      $show "(cd $xdir && $AR x $xabs)"
+	      $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+	      if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
+		:
+	      else
+		$echo "$modename: warning: object name conflicts; renaming object files" 1>&2
+		$echo "$modename: warning: to ensure that they will not overwrite" 1>&2
+		$AR t "$xabs" | sort | uniq -cd | while read -r count name
+		do
+		  i=1
+		  while test "$i" -le "$count"
+		  do
+		   # Put our $i before any first dot (extension)
+		   # Never overwrite any file
+		   name_to="$name"
+		   while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
+		   do
+		     name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
+		   done
+		   $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
+		   $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
+		   i=`expr $i + 1`
+		  done
+		done
+	      fi
+
+	      libobjs="$libobjs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+	    done
+	  fi
+	fi
+
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+	  eval flag=\"$thread_safe_flag_spec\"
+	  linker_flags="$linker_flags $flag"
+	fi
+
+	# Make a backup of the uninstalled library when relinking
+	if test "$mode" = relink; then
+	  $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $?
+	fi
+
+	# Add all flags from the command line.  We here create a library,
+	# but those flags were only added to compile_command and
+	# finalize_command, which are only used when creating executables.
+	# So do it by hand here.
+	compiler_flags="$compiler_flags $add_flags"
+	# Only add it to commands which use CC, instead of LD, i.e.
+	# only to $compiler_flags
+	#linker_flags="$linker_flags $add_flags"
+
+	# Do each of the archive commands.
+	if test "$module" = yes && test -n "$module_cmds" ; then
+	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	    eval cmds=\"$module_expsym_cmds\"
+	  else
+	    eval cmds=\"$module_cmds\"
+	  fi
+	else
+	if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	  eval cmds=\"$archive_expsym_cmds\"
+	else
+	  eval cmds=\"$archive_cmds\"
+	  fi
+	fi
+
+	if test "X$skipped_export" != "X:" && len=`expr "X$cmds" : ".*"` &&
+	   test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  :
+	else
+	  # The command line is too long to link in one step, link piecewise.
+	  $echo "creating reloadable object files..."
+
+	  # Save the value of $output and $libobjs because we want to
+	  # use them later.  If we have whole_archive_flag_spec, we
+	  # want to use save_libobjs as it was before
+	  # whole_archive_flag_spec was expanded, because we can't
+	  # assume the linker understands whole_archive_flag_spec.
+	  # This may have to be revisited, in case too many
+	  # convenience libraries get linked in and end up exceeding
+	  # the spec.
+	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	  fi
+	  save_output=$output
+
+	  # Clear the reloadable object creation command queue and
+	  # initialize k to one.
+	  test_cmds=
+	  concat_cmds=
+	  objlist=
+	  delfiles=
+	  last_robj=
+	  k=1
+	  output=$output_objdir/$save_output-${k}.$objext
+	  # Loop over the list of objects to be linked.
+	  for obj in $save_libobjs
+	  do
+	    eval test_cmds=\"$reload_cmds $objlist $last_robj\"
+	    if test "X$objlist" = X ||
+	       { len=`expr "X$test_cmds" : ".*"` &&
+		 test "$len" -le "$max_cmd_len"; }; then
+	      objlist="$objlist $obj"
+	    else
+	      # The command $test_cmds is almost too long, add a
+	      # command to the queue.
+	      if test "$k" -eq 1 ; then
+		# The first file doesn't have a previous command to add.
+		eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
+	      else
+		# All subsequent reloadable object files will link in
+		# the last one created.
+		eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\"
+	      fi
+	      last_robj=$output_objdir/$save_output-${k}.$objext
+	      k=`expr $k + 1`
+	      output=$output_objdir/$save_output-${k}.$objext
+	      objlist=$obj
+	      len=1
+	    fi
+	  done
+	  # Handle the remaining objects by creating one last
+	  # reloadable object file.  All subsequent reloadable object
+	  # files will link in the last one created.
+	  test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	  eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
+
+	  if ${skipped_export-false}; then
+	    $show "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $run $rm $export_symbols
+	    libobjs=$output
+	    # Append the command to create the export file.
+	    eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\"
+          fi
+
+	  # Set up a command to remove the reloadale object files
+	  # after they are used.
+	  i=0
+	  while test "$i" -lt "$k"
+	  do
+	    i=`expr $i + 1`
+	    delfiles="$delfiles $output_objdir/$save_output-${i}.$objext"
+	  done
+
+	  $echo "creating a temporary reloadable object file: $output"
+
+	  # Loop through the commands generated above and execute them.
+	  save_ifs="$IFS"; IFS='~'
+	  for cmd in $concat_cmds; do
+	    IFS="$save_ifs"
+	    $show "$cmd"
+	    $run eval "$cmd" || exit $?
+	  done
+	  IFS="$save_ifs"
+
+	  libobjs=$output
+	  # Restore the value of output.
+	  output=$save_output
+
+	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	  fi
+	  # Expand the library linking commands again to reset the
+	  # value of $libobjs for piecewise linking.
+
+	  # Do each of the archive commands.
+	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	    eval cmds=\"$archive_expsym_cmds\"
+	  else
+	    eval cmds=\"$archive_cmds\"
+	  fi
+
+	  # Append the command to remove the reloadable object files
+	  # to the just-reset $cmds.
+	  eval cmds=\"\$cmds~$rm $delfiles\"
+	fi
+	save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  $show "$cmd"
+	  $run eval "$cmd" || exit $?
+	done
+	IFS="$save_ifs"
+
+	# Restore the uninstalled library and exit
+	if test "$mode" = relink; then
+	  $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
+	  exit 0
+	fi
+
+	# Create links to the real library.
+	for linkname in $linknames; do
+	  if test "$realname" != "$linkname"; then
+	    $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+	    $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+	  fi
+	done
+
+	# If -module or -export-dynamic was specified, set the dlname.
+	if test "$module" = yes || test "$export_dynamic" = yes; then
+	  # On all known operating systems, these are identical.
+	  dlname="$soname"
+	fi
+      fi
+      ;;
+
+    obj)
+      if test -n "$deplibs"; then
+	$echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	$echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+	$echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+	$echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+      fi
+
+      case $output in
+      *.lo)
+	if test -n "$objs$old_deplibs"; then
+	  $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+	  exit 1
+	fi
+	libobj="$output"
+	obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+	;;
+      *)
+	libobj=
+	obj="$output"
+	;;
+      esac
+
+      # Delete the old objects.
+      $run $rm $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec
+      wl=
+
+      if test -n "$convenience"; then
+	if test -n "$whole_archive_flag_spec"; then
+	  eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+	else
+	  gentop="$output_objdir/${obj}x"
+	  $show "${rm}r $gentop"
+	  $run ${rm}r "$gentop"
+	  $show "$mkdir $gentop"
+	  $run $mkdir "$gentop"
+	  status=$?
+	  if test "$status" -ne 0 && test ! -d "$gentop"; then
+	    exit $status
+	  fi
+	  generated="$generated $gentop"
+
+	  for xlib in $convenience; do
+	    # Extract the objects.
+	    case $xlib in
+	    [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+	    *) xabs=`pwd`"/$xlib" ;;
+	    esac
+	    xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+	    xdir="$gentop/$xlib"
+
+	    $show "${rm}r $xdir"
+	    $run ${rm}r "$xdir"
+	    $show "$mkdir $xdir"
+	    $run $mkdir "$xdir"
+	    status=$?
+	    if test "$status" -ne 0 && test ! -d "$xdir"; then
+	      exit $status
+	    fi
+	    # We will extract separately just the conflicting names and we will no
+	    # longer touch any unique names. It is faster to leave these extract
+	    # automatically by $AR in one run.
+	    $show "(cd $xdir && $AR x $xabs)"
+	    $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+	    if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
+	      :
+	    else
+	      $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
+	      $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
+	      $AR t "$xabs" | sort | uniq -cd | while read -r count name
+	      do
+		i=1
+		while test "$i" -le "$count"
+		do
+		 # Put our $i before any first dot (extension)
+		 # Never overwrite any file
+		 name_to="$name"
+		 while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
+		 do
+		   name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
+		 done
+		 $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
+		 $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
+		 i=`expr $i + 1`
+		done
+	      done
+	    fi
+
+	    reload_conv_objs="$reload_objs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+	  done
+	fi
+      fi
+
+      # Create the old-style object.
+      reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+      output="$obj"
+      eval cmds=\"$reload_cmds\"
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+	IFS="$save_ifs"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+	if test -n "$gentop"; then
+	  $show "${rm}r $gentop"
+	  $run ${rm}r $gentop
+	fi
+
+	exit 0
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+	if test -n "$gentop"; then
+	  $show "${rm}r $gentop"
+	  $run ${rm}r $gentop
+	fi
+
+	# Create an invalid libtool object if no PIC, so that we don't
+	# accidentally link it into a program.
+	# $show "echo timestamp > $libobj"
+	# $run eval "echo timestamp > $libobj" || exit $?
+	exit 0
+      fi
+
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
+	# Only do commands if we really have different PIC objects.
+	reload_objs="$libobjs $reload_conv_objs"
+	output="$libobj"
+	eval cmds=\"$reload_cmds\"
+	save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  $show "$cmd"
+	  $run eval "$cmd" || exit $?
+	done
+	IFS="$save_ifs"
+      fi
+
+      if test -n "$gentop"; then
+	$show "${rm}r $gentop"
+	$run ${rm}r $gentop
+      fi
+
+      exit 0
+      ;;
+
+    prog)
+      case $host in
+	*cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;;
+      esac
+      if test -n "$vinfo"; then
+	$echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+      fi
+
+      if test -n "$release"; then
+	$echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+      fi
+
+      if test "$preload" = yes; then
+	if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown &&
+	   test "$dlopen_self_static" = unknown; then
+	  $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+	fi
+      fi
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+	# On Rhapsody replace the C library is the System framework
+	compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+	finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+	;;
+      esac
+
+      case $host in
+      *darwin*)
+        # Don't allow lazy linking, it breaks C++ global constructors
+        if test "$tagname" = CXX ; then
+        compile_command="$compile_command ${wl}-bind_at_load"
+        finalize_command="$finalize_command ${wl}-bind_at_load"
+        fi
+        ;;
+      esac
+
+      compile_command="$compile_command $compile_deplibs"
+      finalize_command="$finalize_command $finalize_deplibs"
+
+      if test -n "$rpath$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath $xrpath; do
+	  # This is the magic to use -rpath.
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_rpath="$finalize_rpath $libdir" ;;
+	  esac
+	done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) perm_rpath="$perm_rpath $libdir" ;;
+	  esac
+	fi
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+	  case :$dllsearchpath: in
+	  *":$libdir:"*) ;;
+	  *) dllsearchpath="$dllsearchpath:$libdir";;
+	  esac
+	  ;;
+	esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+	# Transform all the library objects into standard objects.
+	compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+      fi
+
+      dlsyms=
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	  dlsyms="${outputname}S.c"
+	else
+	  $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+	fi
+      fi
+
+      if test -n "$dlsyms"; then
+	case $dlsyms in
+	"") ;;
+	*.c)
+	  # Discover the nlist of each of the dlfiles.
+	  nlist="$output_objdir/${outputname}.nm"
+
+	  $show "$rm $nlist ${nlist}S ${nlist}T"
+	  $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+	  # Parse the name list into a source file.
+	  $show "creating $output_objdir/$dlsyms"
+
+	  test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+	  if test "$dlself" = yes; then
+	    $show "generating symbol list for \`$output'"
+
+	    test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+	    # Add our own program objects to the symbol list.
+	    progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	    for arg in $progfiles; do
+	      $show "extracting global C symbols from \`$arg'"
+	      $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+	    done
+
+	    if test -n "$exclude_expsyms"; then
+	      $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      $run eval '$mv "$nlist"T "$nlist"'
+	    fi
+
+	    if test -n "$export_symbols_regex"; then
+	      $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      $run eval '$mv "$nlist"T "$nlist"'
+	    fi
+
+	    # Prepare the list of exported symbols
+	    if test -z "$export_symbols"; then
+	      export_symbols="$output_objdir/$output.exp"
+	      $run $rm $export_symbols
+	      $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	    else
+	      $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+	      $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+	      $run eval 'mv "$nlist"T "$nlist"'
+	    fi
+	  fi
+
+	  for arg in $dlprefiles; do
+	    $show "extracting global C symbols from \`$arg'"
+	    name=`$echo "$arg" | ${SED} -e 's%^.*/%%'`
+	    $run eval '$echo ": $name " >> "$nlist"'
+	    $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+	  done
+
+	  if test -z "$run"; then
+	    # Make sure we have at least an empty file.
+	    test -f "$nlist" || : > "$nlist"
+
+	    if test -n "$exclude_expsyms"; then
+	      $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+	      $mv "$nlist"T "$nlist"
+	    fi
+
+	    # Try sorting and uniquifying the output.
+	    if grep -v "^: " < "$nlist" |
+		if sort -k 3 </dev/null >/dev/null 2>&1; then
+		  sort -k 3
+		else
+		  sort +2
+		fi |
+		uniq > "$nlist"S; then
+	      :
+	    else
+	      grep -v "^: " < "$nlist" > "$nlist"S
+	    fi
+
+	    if test -f "$nlist"S; then
+	      eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+	    else
+	      $echo '/* NONE */' >> "$output_objdir/$dlsyms"
+	    fi
+
+	    $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
+
+	    $echo >> "$output_objdir/$dlsyms" "\
+  {0, (lt_ptr) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	  fi
+
+	  pic_flag_for_symtable=
+	  case $host in
+	  # compiling the symbol table file with pic_flag works around
+	  # a FreeBSD bug that causes programs to crash when -lm is
+	  # linked before any other PIC object.  But we must not use
+	  # pic_flag when linking with -static.  The problem exists in
+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+	  *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+	    case "$compile_command " in
+	    *" -static "*) ;;
+	    *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";;
+	    esac;;
+	  *-*-hpux*)
+	    case "$compile_command " in
+	    *" -static "*) ;;
+	    *) pic_flag_for_symtable=" $pic_flag";;
+	    esac
+	  esac
+
+	  # Now compile the dynamic symbol file.
+	  $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+	  $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+	  # Clean up the generated files.
+	  $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+	  $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+	  # Transform the symbol file into the correct name.
+	  compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+	  finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+	  ;;
+	*)
+	  $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+	  exit 1
+	  ;;
+	esac
+      else
+	# We keep going just in case the user didn't refer to
+	# lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+	# really was required.
+
+	# Nullify the symbol file.
+	compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+	finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      # AIX runtime linking requires linking programs with -Wl,-brtl and libs with -Wl,-G
+      # Also add -bnolibpath to the beginning of the link line, to clear the hardcoded runpath.
+      # Otherwise, things like the -L path to libgcc.a are accidentally hardcoded by ld.
+      # This does not apply on AIX for ia64, which uses a SysV linker.
+      case "$host" in
+        ia64-*-aix5*) ;;
+        *-*-aix4* | *-*-aix5*)
+                   compile_command=`$echo "X$compile_command $wl-brtl" | $Xsed -e "s/\$CC/\$CC $wl-bnolibpath/1"`
+                   finalize_command=`$echo "X$finalize_command $wl-brtl" | $Xsed -e "s/\$CC/\$CC $wl-bnolibpath/1"` ;;
+      esac
+
+      if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+	# Replace the output file specification.
+	compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+	link_command="$compile_command$compile_rpath"
+
+	# We have no uninstalled library dependencies, so finalize right now.
+	$show "$link_command"
+	$run eval "$link_command"
+	status=$?
+
+	# Delete the generated files.
+	if test -n "$dlsyms"; then
+	  $show "$rm $output_objdir/${outputname}S.${objext}"
+	  $run $rm "$output_objdir/${outputname}S.${objext}"
+	fi
+
+	exit $status
+      fi
+
+      if test -n "$shlibpath_var"; then
+	# We should set the shlibpath_var
+	rpath=
+	for dir in $temp_rpath; do
+	  case $dir in
+	  [\\/]* | [A-Za-z]:[\\/]*)
+	    # Absolute path.
+	    rpath="$rpath$dir:"
+	    ;;
+	  *)
+	    # Relative path: add a thisdir entry.
+	    rpath="$rpath\$thisdir/$dir:"
+	    ;;
+	  esac
+	done
+	temp_rpath="$rpath"
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+	if test -n "$perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $perm_rpath; do
+	    rpath="$rpath$dir:"
+	  done
+	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+	if test -n "$finalize_perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $finalize_perm_rpath; do
+	    rpath="$rpath$dir:"
+	  done
+	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+      fi
+
+      if test "$no_install" = yes; then
+	# We don't need to create a wrapper script.
+	link_command="$compile_var$compile_command$compile_rpath"
+	# Replace the output file specification.
+	link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+	# Delete the old output file.
+	$run $rm $output
+	# Link the executable and exit
+	$show "$link_command"
+	$run eval "$link_command" || exit $?
+	exit 0
+      fi
+
+      if test "$hardcode_action" = relink; then
+	# Fast installation is not supported
+	link_command="$compile_var$compile_command$compile_rpath"
+	relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+	$echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+	$echo "$modename: \`$output' will be relinked during installation" 1>&2
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+	  else
+	    # fast_install is set to needless
+	    relink_command=
+	  fi
+	else
+	  link_command="$compile_var$compile_command$compile_rpath"
+	  relink_command="$finalize_var$finalize_command$finalize_rpath"
+	fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      $show "$link_command"
+      $run eval "$link_command" || exit $?
+
+      # Now create the wrapper script.
+      $show "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+	# Preserve any variables that may affect compiler behavior
+	for var in $variables_saved_for_relink; do
+	  if eval test -z \"\${$var+set}\"; then
+	    relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+	  elif eval var_value=\$$var; test -z "$var_value"; then
+	    relink_command="$var=; export $var; $relink_command"
+	  else
+	    var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+	    relink_command="$var=\"$var_value\"; export $var; $relink_command"
+	  fi
+	done
+	relink_command="(cd `pwd`; $relink_command)"
+	relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Quote $echo for shipping.
+      if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
+	case $0 in
+	[\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
+	*) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+	esac
+	qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+      else
+	qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if our run command is non-null.
+      if test -z "$run"; then
+	# win32 will think the script is a binary if it has
+	# a .exe suffix, so we strip it off here.
+	case $output in
+	  *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;;
+	esac
+	# test for cygwin because mv fails w/o .exe extensions
+	case $host in
+	  *cygwin*)
+	    exeext=.exe
+	    outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;;
+	  *) exeext= ;;
+	esac
+	case $host in
+	  *cygwin* | *mingw* )
+	    cwrappersource=`$echo ${objdir}/lt-${output}.c`
+	    cwrapper=`$echo ${output}.exe`
+	    $rm $cwrappersource $cwrapper
+	    trap "$rm $cwrappersource $cwrapper; exit 1" 1 2 15
+
+	    cat > $cwrappersource <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+
+   The $output program cannot be directly executed until all the libtool
+   libraries that it depends on are installed.
+   
+   This wrapper executable should never be moved out of the build directory.
+   If it is, it will not operate correctly.
+
+   Currently, it simply execs the wrapper *script* "/bin/sh $output",
+   but could eventually absorb all of the scripts functionality and
+   exec $objdir/$outputname directly.
+*/
+EOF
+	    cat >> $cwrappersource<<"EOF"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef DIR_SEPARATOR
+#define DIR_SEPARATOR '/'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
+#define HAVE_DOS_BASED_FILE_SYSTEM
+#ifndef DIR_SEPARATOR_2 
+#define DIR_SEPARATOR_2 '\\'
+#endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+        (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+const char *program_name = NULL;
+
+void * xmalloc (size_t num);
+char * xstrdup (const char *string);
+char * basename (const char *name);
+char * fnqualify(const char *path);
+char * strendzap(char *str, const char *pat);
+void lt_fatal (const char *message, ...);
+
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int i;
+  
+  program_name = (char *) xstrdup ((char *) basename (argv[0]));
+  newargz = XMALLOC(char *, argc+2);
+EOF
+
+	    cat >> $cwrappersource <<EOF
+  newargz[0] = "$SHELL";
+EOF
+
+	    cat >> $cwrappersource <<"EOF"
+  newargz[1] = fnqualify(argv[0]);
+  /* we know the script has the same name, without the .exe */
+  /* so make sure newargz[1] doesn't end in .exe */
+  strendzap(newargz[1],".exe"); 
+  for (i = 1; i < argc; i++)
+    newargz[i+1] = xstrdup(argv[i]);
+  newargz[argc+1] = NULL;
+EOF
+
+	    cat >> $cwrappersource <<EOF
+  execv("$SHELL",newargz);
+EOF
+
+	    cat >> $cwrappersource <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+  void * p = (void *) malloc (num);
+  if (!p)
+    lt_fatal ("Memory exhausted");
+
+  return p;
+}
+
+char * 
+xstrdup (const char *string)
+{
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL
+;
+}
+
+char *
+basename (const char *name)
+{
+  const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  /* Skip over the disk name in MSDOS pathnames. */
+  if (isalpha (name[0]) && name[1] == ':') 
+    name += 2;
+#endif
+
+  for (base = name; *name; name++)
+    if (IS_DIR_SEPARATOR (*name))
+      base = name + 1;
+  return (char *) base;
+}
+
+char * 
+fnqualify(const char *path)
+{
+  size_t size;
+  char *p;
+  char tmp[LT_PATHMAX + 1];
+
+  assert(path != NULL);
+
+  /* Is it qualified already? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  if (isalpha (path[0]) && path[1] == ':')
+    return xstrdup (path);
+#endif
+  if (IS_DIR_SEPARATOR (path[0]))
+    return xstrdup (path);
+
+  /* prepend the current directory */
+  /* doesn't handle '~' */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal ("getcwd failed");
+  size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */
+  p = XMALLOC(char, size);
+  sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path);
+  return p;
+}
+
+char *
+strendzap(char *str, const char *pat) 
+{
+  size_t len, patlen;
+
+  assert(str != NULL);
+  assert(pat != NULL);
+
+  len = strlen(str);
+  patlen = strlen(pat);
+
+  if (patlen <= len)
+  {
+    str += len - patlen;
+    if (strcmp(str, pat) == 0)
+      *str = '\0';
+  }
+  return str;
+}
+
+static void
+lt_error_core (int exit_status, const char * mode, 
+          const char * message, va_list ap)
+{
+  fprintf (stderr, "%s: %s: ", program_name, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
+  va_end (ap);
+}
+EOF
+	  # we should really use a build-platform specific compiler
+	  # here, but OTOH, the wrappers (shell script and this C one)
+	  # are only useful if you want to execute the "real" binary.
+	  # Since the "real" binary is built for $host, then this
+	  # wrapper might as well be built for $host, too.
+	  $run $LTCC -s -o $cwrapper $cwrappersource
+	  ;;
+	esac
+	$rm $output
+	trap "$rm $output; exit 1" 1 2 15
+
+	$echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='${SED} -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variable:
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$echo are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    echo=\"$qecho\"
+    file=\"\$0\"
+    # Make sure echo works.
+    if test \"X\$1\" = X--no-reexec; then
+      # Discard the --no-reexec flag, and continue.
+      shift
+    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+      # Yippee, \$echo works!
+      :
+    else
+      # Restart under the correct shell, and then maybe \$echo will work.
+      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+    fi
+  fi\
+"
+	$echo >> $output "\
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+	if test "$fast_install" = yes; then
+	  $echo >> $output "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" || \\
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $mkdir \"\$progdir\"
+    else
+      $rm \"\$progdir/\$file\"
+    fi"
+
+	  $echo >> $output "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+	$echo \"\$relink_command_output\" >&2
+	$rm \"\$progdir/\$file\"
+	exit 1
+      fi
+    fi
+
+    $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $rm \"\$progdir/\$program\";
+      $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $rm \"\$progdir/\$file\"
+  fi"
+	else
+	  $echo >> $output "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+	fi
+
+	$echo >> $output "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+	# Export our shlibpath_var if we have one.
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $echo >> $output "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+	fi
+
+	# fixup the dll searchpath if we need to.
+	if test -n "$dllsearchpath"; then
+	  $echo >> $output "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+	fi
+
+	$echo >> $output "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+"
+	case $host in
+	# Backslashes separate directories on plain windows
+	*-*-mingw | *-*-os2*)
+	  $echo >> $output "\
+      exec \$progdir\\\\\$program \${1+\"\$@\"}
+"
+	  ;;
+
+	*)
+	  $echo >> $output "\
+      exec \$progdir/\$program \${1+\"\$@\"}
+"
+	  ;;
+	esac
+	$echo >> $output "\
+      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+      exit 1
+    fi
+  else
+    # The program doesn't exist.
+    \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+    \$echo \"This script is just a wrapper for \$program.\" 1>&2
+    $echo \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+	chmod +x $output
+      fi
+      exit 0
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+	oldobjs="$libobjs_save"
+	addlibs="$convenience"
+	build_libtool_libs=no
+      else
+	if test "$build_libtool_libs" = module; then
+	  oldobjs="$libobjs_save"
+	  build_libtool_libs=no
+	else
+	  oldobjs="$old_deplibs $non_pic_objects"
+	fi
+	addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+	gentop="$output_objdir/${outputname}x"
+	$show "${rm}r $gentop"
+	$run ${rm}r "$gentop"
+	$show "$mkdir $gentop"
+	$run $mkdir "$gentop"
+	status=$?
+	if test "$status" -ne 0 && test ! -d "$gentop"; then
+	  exit $status
+	fi
+	generated="$generated $gentop"
+
+	# Add in members from convenience archives.
+	for xlib in $addlibs; do
+	  # Extract the objects.
+	  case $xlib in
+	  [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+	  *) xabs=`pwd`"/$xlib" ;;
+	  esac
+	  xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+	  xdir="$gentop/$xlib"
+
+	  $show "${rm}r $xdir"
+	  $run ${rm}r "$xdir"
+	  $show "$mkdir $xdir"
+	  $run $mkdir "$xdir"
+	  status=$?
+	  if test "$status" -ne 0 && test ! -d "$xdir"; then
+	    exit $status
+	  fi
+	  # We will extract separately just the conflicting names and we will no
+	  # longer touch any unique names. It is faster to leave these extract
+	  # automatically by $AR in one run.
+	  $show "(cd $xdir && $AR x $xabs)"
+	  $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+	  if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
+	    :
+	  else
+	    $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
+	    $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
+	    $AR t "$xabs" | sort | uniq -cd | while read -r count name
+	    do
+	      i=1
+	      while test "$i" -le "$count"
+	      do
+	       # Put our $i before any first dot (extension)
+	       # Never overwrite any file
+	       name_to="$name"
+	       while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
+	       do
+		 name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
+	       done
+	       $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
+	       $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
+	       i=`expr $i + 1`
+	      done
+	    done
+	  fi
+
+	  oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
+	done
+      fi
+
+      compiler_flags="$compiler_flags $add_flags"
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+	eval cmds=\"$old_archive_from_new_cmds\"
+      else
+	eval cmds=\"$old_archive_cmds\"
+
+	if len=`expr "X$cmds" : ".*"` &&
+	     test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  :
+	else
+	  # the command line is too long to link in one step, link in parts
+	  $echo "using piecewise archive linking..."
+	  save_RANLIB=$RANLIB
+	  RANLIB=:
+	  objlist=
+	  concat_cmds=
+	  save_oldobjs=$oldobjs
+	  # GNU ar 2.10+ was changed to match POSIX; thus no paths are
+	  # encoded into archives.  This makes 'ar r' malfunction in
+	  # this piecewise linking case whenever conflicting object
+	  # names appear in distinct ar calls; check, warn and compensate.
+	    if (for obj in $save_oldobjs
+	    do
+	      $echo "X$obj" | $Xsed -e 's%^.*/%%'
+	    done | sort | sort -uc >/dev/null 2>&1); then
+	    :
+	  else
+	    $echo "$modename: warning: object name conflicts; overriding AR_FLAGS to 'cq'" 1>&2
+	    $echo "$modename: warning: to ensure that POSIX-compatible ar will work" 1>&2
+	    AR_FLAGS=cq
+	  fi
+	  # Is there a better way of finding the last object in the list?
+	  for obj in $save_oldobjs
+	  do
+	    last_oldobj=$obj
+	  done  
+	  for obj in $save_oldobjs
+	  do
+	    oldobjs="$objlist $obj"
+	    objlist="$objlist $obj"
+	    eval test_cmds=\"$old_archive_cmds\"
+	    if len=`expr "X$test_cmds" : ".*"` &&
+	       test "$len" -le "$max_cmd_len"; then
+	      :
+	    else
+	      # the above command should be used before it gets too long
+	      oldobjs=$objlist
+	      if test "$obj" = "$last_oldobj" ; then
+	        RANLIB=$save_RANLIB
+	      fi  
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+	      objlist=
+	    fi
+	  done
+	  RANLIB=$save_RANLIB
+	  oldobjs=$objlist
+	  if test "X$oldobjs" = "X" ; then
+	    eval cmds=\"\$concat_cmds\"
+	  else
+	    eval cmds=\"\$concat_cmds~$old_archive_cmds\"
+	  fi
+	fi
+      fi
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+	IFS="$save_ifs"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$generated"; then
+      $show "${rm}r$generated"
+      $run ${rm}r$generated
+    fi
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      $show "creating $output"
+
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+	if eval test -z \"\${$var+set}\"; then
+	  relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+	elif eval var_value=\$$var; test -z "$var_value"; then
+	  relink_command="$var=; export $var; $relink_command"
+	else
+	  var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+	  relink_command="$var=\"$var_value\"; export $var; $relink_command"
+	fi
+      done
+      # Quote the link command for shipping.
+      relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      if test "$hardcode_automatic" = yes ; then
+        relink_command=
+      fi  
+      # Only create the output if not a dry run.
+      if test -z "$run"; then
+	for installed in no yes; do
+	  if test "$installed" = yes; then
+	    if test -z "$install_libdir"; then
+	      break
+	    fi
+	    output="$output_objdir/$outputname"i
+	    # Replace all uninstalled libtool libraries with the installed ones
+	    newdependency_libs=
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      *.la)
+		name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'`
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		if test -z "$libdir"; then
+		  $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+		  exit 1
+		fi
+		newdependency_libs="$newdependency_libs $libdir/$name"
+		;;
+	      *) newdependency_libs="$newdependency_libs $deplib" ;;
+	      esac
+	    done
+	    dependency_libs="$newdependency_libs"
+	    newdlfiles=
+	    for lib in $dlfiles; do
+	      name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+	      eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+	      if test -z "$libdir"; then
+		$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+		exit 1
+	      fi
+	      newdlfiles="$newdlfiles $libdir/$name"
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+	      eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+	      if test -z "$libdir"; then
+		$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+		exit 1
+	      fi
+	      newdlprefiles="$newdlprefiles $libdir/$name"
+	    done
+	    dlprefiles="$newdlprefiles"
+	  fi
+	  $rm $output
+	  # place dlname in correct position for cygwin
+	  tdlname=$dlname
+	  case $host,$output,$installed,$module,$dlname in
+	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+	  esac
+	  $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+	  if test "$installed" = no && test "$need_relink" = yes && test "$fast_install" = no; then
+	    $echo >> $output "\
+relink_command=\"$relink_command\""
+	  fi
+	done
+      fi
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+      $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $?
+      ;;
+    esac
+    exit 0
+    ;;
+
+  # libtool install mode
+  install)
+    modename="$modename: install"
+
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+       # Allow the use of GNU shtool's install command.
+       $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then
+      # Aesthetically quote it.
+      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	arg="\"$arg\""
+	;;
+      esac
+      install_prog="$arg "
+      arg="$1"
+      shift
+    else
+      install_prog=
+      arg="$nonopt"
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+    case $arg in
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+      arg="\"$arg\""
+      ;;
+    esac
+    install_prog="$install_prog$arg"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+	files="$files $dest"
+	dest="$arg"
+	continue
+      fi
+
+      case $arg in
+      -d) isdir=yes ;;
+      -f) prev="-f" ;;
+      -g) prev="-g" ;;
+      -m) prev="-m" ;;
+      -o) prev="-o" ;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*) ;;
+
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  prev=
+	else
+	  dest="$arg"
+	  continue
+	fi
+	;;
+      esac
+
+      # Aesthetically quote the argument.
+      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*)
+	arg="\"$arg\""
+	;;
+      esac
+      install_prog="$install_prog $arg"
+    done
+
+    if test -z "$install_prog"; then
+      $echo "$modename: you must specify an install program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prev' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	$echo "$modename: no file or destination specified" 1>&2
+      else
+	$echo "$modename: you must specify a destination" 1>&2
+      fi
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Strip any trailing slash from the destination.
+    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$destdir" = "X$dest" && destdir=.
+      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files
+      if test "$#" -gt 2; then
+	$echo "$modename: \`$dest' is not a directory" 1>&2
+	$echo "$help" 1>&2
+	exit 1
+      fi
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case $file in
+	*.lo) ;;
+	*)
+	  $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	  ;;
+	esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+	# Do the static libraries later.
+	staticlibs="$staticlibs $file"
+	;;
+
+      *.la)
+	# Check to see that this really is a libtool archive.
+	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	fi
+
+	library_names=
+	old_library=
+	relink_command=
+	# If there is no directory component, then add one.
+	case $file in
+	*/* | *\\*) . $file ;;
+	*) . ./$file ;;
+	esac
+
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) current_libdirs="$current_libdirs $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) future_libdirs="$future_libdirs $libdir" ;;
+	  esac
+	fi
+
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/
+	test "X$dir" = "X$file/" && dir=
+	dir="$dir$objdir"
+
+	if test -n "$relink_command"; then
+	  # Determine the prefix the user has applied to our future dir.
+	  inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"`
+
+	  # Don't allow the user to place us outside of our expected
+	  # location b/c this prevents finding dependent libraries that
+	  # are installed to the same prefix.
+	  # At present, this check doesn't affect windows .dll's that
+	  # are installed into $libdir/../bin (currently, that works fine)
+	  # but it's something to keep an eye on.
+	  if test "$inst_prefix_dir" = "$destdir"; then
+	    $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2
+	    exit 1
+	  fi
+
+	  if test -n "$inst_prefix_dir"; then
+	    # Stick the inst_prefix_dir data into the link command.
+	    relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+	  else
+	    relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+	  fi
+
+	  $echo "$modename: warning: relinking \`$file'" 1>&2
+	  $show "$relink_command"
+	  if $run eval "$relink_command"; then :
+	  else
+	    $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+	    exit 1
+	  fi
+	fi
+
+	# See the names of the shared library.
+	set dummy $library_names
+	if test -n "$2"; then
+	  realname="$2"
+	  shift
+	  shift
+
+	  srcname="$realname"
+	  test -n "$relink_command" && srcname="$realname"T
+
+	  # Install the shared library and build the symlinks.
+	  $show "$install_prog $dir/$srcname $destdir/$realname"
+	  $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $?
+	  if test -n "$stripme" && test -n "$striplib"; then
+	    $show "$striplib $destdir/$realname"
+	    $run eval "$striplib $destdir/$realname" || exit $?
+	  fi
+
+	  if test "$#" -gt 0; then
+	    # Delete the old symlinks, and create new ones.
+	    for linkname
+	    do
+	      if test "$linkname" != "$realname"; then
+		$show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+		$run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+	      fi
+	    done
+	  fi
+
+	  # Do each command in the postinstall commands.
+	  lib="$destdir/$realname"
+	  eval cmds=\"$postinstall_cmds\"
+	  save_ifs="$IFS"; IFS='~'
+	  for cmd in $cmds; do
+	    IFS="$save_ifs"
+	    $show "$cmd"
+	    $run eval "$cmd" || exit $?
+	  done
+	  IFS="$save_ifs"
+	fi
+
+	# Install the pseudo-library for information purposes.
+	name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	instname="$dir/$name"i
+	$show "$install_prog $instname $destdir/$name"
+	$run eval "$install_prog $instname $destdir/$name" || exit $?
+
+	# Maybe install the static library, too.
+	test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+	;;
+
+      *.lo)
+	# Install (i.e. copy) a libtool object.
+
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	  destfile="$destdir/$destfile"
+	fi
+
+	# Deduce the name of the destination old-style object file.
+	case $destfile in
+	*.lo)
+	  staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+	  ;;
+	*.$objext)
+	  staticdest="$destfile"
+	  destfile=
+	  ;;
+	*)
+	  $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	  ;;
+	esac
+
+	# Install the libtool object if requested.
+	if test -n "$destfile"; then
+	  $show "$install_prog $file $destfile"
+	  $run eval "$install_prog $file $destfile" || exit $?
+	fi
+
+	# Install the old object if enabled.
+	if test "$build_old_libs" = yes; then
+	  # Deduce the name of the old-style object file.
+	  staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+	  $show "$install_prog $staticobj $staticdest"
+	  $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+	fi
+	exit 0
+	;;
+
+      *)
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+	  destfile="$destdir/$destfile"
+	fi
+
+	# If the file is missing, and there is a .exe on the end, strip it
+	# because it is most likely a libtool script we actually want to
+	# install
+	stripped_ext=""
+	case $file in
+	  *.exe)
+	    if test ! -f "$file"; then
+	      file=`$echo $file|${SED} 's,.exe$,,'`
+	      stripped_ext=".exe"
+	    fi
+	    ;;
+	esac
+
+	# Do a test to see if this is really a libtool program.
+	case $host in
+	*cygwin*|*mingw*)
+	    wrapper=`$echo $file | ${SED} -e 's,.exe$,,'`
+	    ;;
+	*)
+	    wrapper=$file
+	    ;;
+	esac
+	if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then
+	  notinst_deplibs=
+	  relink_command=
+
+	  # To insure that "foo" is sourced, and not "foo.exe",
+	  # finese the cygwin/MSYS system by explicitly sourcing "foo."
+	  # which disallows the automatic-append-.exe behavior.
+	  case $build in
+	  *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
+	  *) wrapperdot=${wrapper} ;;
+	  esac
+	  # If there is no directory component, then add one.
+	  case $file in
+	  */* | *\\*) . ${wrapperdot} ;;
+	  *) . ./${wrapperdot} ;;
+	  esac
+
+	  # Check the variables that should have been set.
+	  if test -z "$notinst_deplibs"; then
+	    $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2
+	    exit 1
+	  fi
+
+	  finalize=yes
+	  for lib in $notinst_deplibs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      # If there is no directory component, then add one.
+	      case $lib in
+	      */* | *\\*) . $lib ;;
+	      *) . ./$lib ;;
+	      esac
+	    fi
+	    libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+	      finalize=no
+	    fi
+	  done
+
+	  relink_command=
+	  # To insure that "foo" is sourced, and not "foo.exe",
+	  # finese the cygwin/MSYS system by explicitly sourcing "foo."
+	  # which disallows the automatic-append-.exe behavior.
+	  case $build in
+	  *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
+	  *) wrapperdot=${wrapper} ;;
+	  esac
+	  # If there is no directory component, then add one.
+	  case $file in
+	  */* | *\\*) . ${wrapperdot} ;;
+	  *) . ./${wrapperdot} ;;
+	  esac
+
+	  outputname=
+	  if test "$fast_install" = no && test -n "$relink_command"; then
+	    if test "$finalize" = yes && test -z "$run"; then
+	      tmpdir="/tmp"
+	      test -n "$TMPDIR" && tmpdir="$TMPDIR"
+	      tmpdir="$tmpdir/libtool-$$"
+	      if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
+	      else
+		$echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
+		continue
+	      fi
+	      file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'`
+	      outputname="$tmpdir/$file"
+	      # Replace the output file specification.
+	      relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+	      $show "$relink_command"
+	      if $run eval "$relink_command"; then :
+	      else
+		$echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+		${rm}r "$tmpdir"
+		continue
+	      fi
+	      file="$outputname"
+	    else
+	      $echo "$modename: warning: cannot relink \`$file'" 1>&2
+	    fi
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+	  fi
+	fi
+
+	# remove .exe since cygwin /usr/bin/install will append another
+	# one anyways
+	case $install_prog,$host in
+	*/usr/bin/install*,*cygwin*)
+	  case $file:$destfile in
+	  *.exe:*.exe)
+	    # this is ok
+	    ;;
+	  *.exe:*)
+	    destfile=$destfile.exe
+	    ;;
+	  *:*.exe)
+	    destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'`
+	    ;;
+	  esac
+	  ;;
+	esac
+	$show "$install_prog$stripme $file $destfile"
+	$run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+	test -n "$outputname" && ${rm}r "$tmpdir"
+	;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      $show "$install_prog $file $oldlib"
+      $run eval "$install_prog \$file \$oldlib" || exit $?
+
+      if test -n "$stripme" && test -n "$striplib"; then
+	$show "$old_striplib $oldlib"
+	$run eval "$old_striplib $oldlib" || exit $?
+      fi
+
+      # Do each command in the postinstall commands.
+      eval cmds=\"$old_postinstall_cmds\"
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+	IFS="$save_ifs"
+	$show "$cmd"
+	$run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$future_libdirs"; then
+      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+    fi
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      test -n "$run" && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL $0 --finish$current_libdirs'
+    else
+      exit 0
+    fi
+    ;;
+
+  # libtool finish mode
+  finish)
+    modename="$modename: finish"
+    libdirs="$nonopt"
+    admincmds=
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for dir
+      do
+	libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  eval cmds=\"$finish_cmds\"
+	  save_ifs="$IFS"; IFS='~'
+	  for cmd in $cmds; do
+	    IFS="$save_ifs"
+	    $show "$cmd"
+	    $run eval "$cmd" || admincmds="$admincmds
+       $cmd"
+	  done
+	  IFS="$save_ifs"
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $run eval "$cmds" || admincmds="$admincmds
+       $cmds"
+	fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    exit 0
+
+    $echo "----------------------------------------------------------------------"
+    $echo "Libraries have been installed in:"
+    for libdir in $libdirs; do
+      $echo "   $libdir"
+    done
+    $echo
+    $echo "If you ever happen to want to link against installed libraries"
+    $echo "in a given directory, LIBDIR, you must either use libtool, and"
+    $echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+    $echo "flag during linking and do at least one of the following:"
+    if test -n "$shlibpath_var"; then
+      $echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+      $echo "     during execution"
+    fi
+    if test -n "$runpath_var"; then
+      $echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+      $echo "     during linking"
+    fi
+    if test -n "$hardcode_libdir_flag_spec"; then
+      libdir=LIBDIR
+      eval flag=\"$hardcode_libdir_flag_spec\"
+
+      $echo "   - use the \`$flag' linker flag"
+    fi
+    if test -n "$admincmds"; then
+      $echo "   - have your system administrator run these commands:$admincmds"
+    fi
+    if test -f /etc/ld.so.conf; then
+      $echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+    fi
+    $echo
+    $echo "See any operating system documentation about shared libraries for"
+    $echo "more information, such as the ld(1) and ld.so(8) manual pages."
+    $echo "----------------------------------------------------------------------"
+    exit 0
+    ;;
+
+  # libtool execute mode
+  execute)
+    modename="$modename: execute"
+
+    # The first argument is the command name.
+    cmd="$nonopt"
+    if test -z "$cmd"; then
+      $echo "$modename: you must specify a COMMAND" 1>&2
+      $echo "$help"
+      exit 1
+    fi
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      if test ! -f "$file"; then
+	$echo "$modename: \`$file' is not a file" 1>&2
+	$echo "$help" 1>&2
+	exit 1
+      fi
+
+      dir=
+      case $file in
+      *.la)
+	# Check to see that this really is a libtool archive.
+	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+	else
+	  $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+	  $echo "$help" 1>&2
+	  exit 1
+	fi
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+
+	# If there is no directory component, then add one.
+	case $file in
+	*/* | *\\*) . $file ;;
+	*) . ./$file ;;
+	esac
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+	  continue
+	fi
+
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$dir" = "X$file" && dir=.
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  dir="$dir/$objdir"
+	else
+	  $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+	  exit 1
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+	test "X$dir" = "X$file" && dir=.
+	;;
+
+      *)
+	$echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+	continue
+	;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -*) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  # If there is no directory component, then add one.
+	  case $file in
+	  */* | *\\*) . $file ;;
+	  *) . ./$file ;;
+	  esac
+
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	fi
+	;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+      args="$args \"$file\""
+    done
+
+    if test -z "$run"; then
+      if test -n "$shlibpath_var"; then
+	# Export the shlibpath_var.
+	eval "export $shlibpath_var"
+      fi
+
+      # Restore saved environment variables
+      if test "${save_LC_ALL+set}" = set; then
+	LC_ALL="$save_LC_ALL"; export LC_ALL
+      fi
+      if test "${save_LANG+set}" = set; then
+	LANG="$save_LANG"; export LANG
+      fi
+
+      # Now prepare to actually exec the command.
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+	$echo "export $shlibpath_var"
+      fi
+      $echo "$cmd$args"
+      exit 0
+    fi
+    ;;
+
+  # libtool clean and uninstall mode
+  clean | uninstall)
+    modename="$modename: $mode"
+    rm="$nonopt"
+    files=
+    rmforce=
+    exit_status=0
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    for arg
+    do
+      case $arg in
+      -f) rm="$rm $arg"; rmforce=yes ;;
+      -*) rm="$rm $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    if test -z "$rm"; then
+      $echo "$modename: you must specify an RM program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    rmdirs=
+
+    origobjdir="$objdir"
+    for file in $files; do
+      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$dir" = "X$file"; then
+	dir=.
+	objdir="$origobjdir"
+      else
+	objdir="$dir/$origobjdir"
+      fi
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+      test "$mode" = uninstall && objdir="$dir"
+
+      # Remember objdir for removal later, being careful to avoid duplicates
+      if test "$mode" = clean; then
+	case " $rmdirs " in
+	  *" $objdir "*) ;;
+	  *) rmdirs="$rmdirs $objdir" ;;
+	esac
+      fi
+
+      # Don't error if the file doesn't exist and rm -f was used.
+      if (test -L "$file") >/dev/null 2>&1 \
+	|| (test -h "$file") >/dev/null 2>&1 \
+	|| test -f "$file"; then
+	:
+      elif test -d "$file"; then
+	exit_status=1
+	continue
+      elif test "$rmforce" = yes; then
+	continue
+      fi
+
+      rmfiles="$file"
+
+      case $name in
+      *.la)
+	# Possibly a libtool archive, so verify it.
+	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	  . $dir/$name
+
+	  # Delete the libtool libraries and symlinks.
+	  for n in $library_names; do
+	    rmfiles="$rmfiles $objdir/$n"
+	  done
+	  test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+	  test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+
+	  if test "$mode" = uninstall; then
+	    if test -n "$library_names"; then
+	      # Do each command in the postuninstall commands.
+	      eval cmds=\"$postuninstall_cmds\"
+	      save_ifs="$IFS"; IFS='~'
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		$show "$cmd"
+		$run eval "$cmd"
+		if test "$?" -ne 0 && test "$rmforce" != yes; then
+		  exit_status=1
+		fi
+	      done
+	      IFS="$save_ifs"
+	    fi
+
+	    if test -n "$old_library"; then
+	      # Do each command in the old_postuninstall commands.
+	      eval cmds=\"$old_postuninstall_cmds\"
+	      save_ifs="$IFS"; IFS='~'
+	      for cmd in $cmds; do
+		IFS="$save_ifs"
+		$show "$cmd"
+		$run eval "$cmd"
+		if test "$?" -ne 0 && test "$rmforce" != yes; then
+		  exit_status=1
+		fi
+	      done
+	      IFS="$save_ifs"
+	    fi
+	    # FIXME: should reinstall the best remaining shared library.
+	  fi
+	fi
+	;;
+
+      *.lo)
+	# Possibly a libtool object, so verify it.
+	if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+
+	  # Read the .lo file
+	  . $dir/$name
+
+	  # Add PIC object to the list of files to remove.
+	  if test -n "$pic_object" \
+	     && test "$pic_object" != none; then
+	    rmfiles="$rmfiles $dir/$pic_object"
+	  fi
+
+	  # Add non-PIC object to the list of files to remove.
+	  if test -n "$non_pic_object" \
+	     && test "$non_pic_object" != none; then
+	    rmfiles="$rmfiles $dir/$non_pic_object"
+	  fi
+	fi
+	;;
+
+      *)
+	if test "$mode" = clean ; then
+	  noexename=$name
+	  case $file in
+	  *.exe) 
+	    file=`$echo $file|${SED} 's,.exe$,,'`
+	    noexename=`$echo $name|${SED} 's,.exe$,,'`
+	    # $file with .exe has already been added to rmfiles,
+	    # add $file without .exe
+	    rmfiles="$rmfiles $file"
+	    ;;
+	  esac
+	  # Do a test to see if this is a libtool program.
+	  if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+	    relink_command=
+	    . $dir/$noexename
+
+	    # note $name still contains .exe if it was in $file originally
+	    # as does the version of $file that was added into $rmfiles
+	    rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+	    if test "$fast_install" = yes && test -n "$relink_command"; then
+	      rmfiles="$rmfiles $objdir/lt-$name"
+	    fi
+	    if test "X$noexename" != "X$name" ; then
+	      rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+	    fi
+	  fi
+	fi
+	;;
+      esac
+      $show "$rm $rmfiles"
+      $run $rm $rmfiles || exit_status=1
+    done
+    objdir="$origobjdir"
+
+    # Try to remove the ${objdir}s in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+	$show "rmdir $dir"
+	$run rmdir $dir >/dev/null 2>&1
+      fi
+    done
+
+    exit $exit_status
+    ;;
+
+  "")
+    $echo "$modename: you must specify a MODE" 1>&2
+    $echo "$generic_help" 1>&2
+    exit 1
+    ;;
+  esac
+
+  if test -z "$exec_cmd"; then
+    $echo "$modename: invalid operation mode \`$mode'" 1>&2
+    $echo "$generic_help" 1>&2
+    exit 1
+  fi
+fi # test -z "$show_help"
+
+if test -n "$exec_cmd"; then
+  eval exec $exec_cmd
+  exit 1
+fi
+
+# We need to display help for each of the modes.
+case $mode in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+    --config          show all configuration variables
+    --debug           enable verbose shell tracing
+-n, --dry-run         display commands without modifying any files
+    --features        display basic configuration information and exit
+    --finish          same as \`--mode=finish'
+    --help            display this help message and exit
+    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
+    --quiet           same as \`--silent'
+    --silent          don't print informational messages
+    --tag=TAG         use configuration variables from tag TAG
+    --version         print version information
+
+MODE must be one of the following:
+
+      clean           remove files from the build directory
+      compile         compile a source file into a libtool object
+      execute         automatically set library path, then run a program
+      finish          complete the installation of libtool libraries
+      install         install libraries or executables
+      link            create a library or an executable
+      uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE.
+
+Report bugs to <bug-libtool@gnu.org>."
+  exit 0
+  ;;
+
+clean)
+  $echo \
+"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+compile)
+  $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -prefer-pic       try to building PIC objects only
+  -prefer-non-pic   try to building non-PIC objects only
+  -static           always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+  ;;
+
+execute)
+  $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+  ;;
+
+finish)
+  $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+  ;;
+
+install)
+  $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+  ;;
+
+link)
+  $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+		    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+		    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -static           do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+		    specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+  ;;
+
+uninstall)
+  $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+*)
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+  ;;
+esac
+
+$echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries.  Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them.  This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration.  But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
Index: /branches/rel3/psModules/missing
===================================================================
--- /branches/rel3/psModules/missing	(revision 2163)
+++ /branches/rel3/psModules/missing	(revision 2163)
@@ -0,0 +1,336 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# 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; either version 2, or (at your option)
+# any later version.
+
+# 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+case "$1" in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]"
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing 0.4 - GNU automake"
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+  aclocal*)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case "$f" in
+      *:*) touch_files="$touch_files "`echo "$f" |
+				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+	   sed 's/\.am$/.in/' |
+	   while read f; do touch "$f"; done
+    ;;
+
+  autom4te)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1Help2man' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+	case "$LASTARG" in
+	*.y)
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" y.tab.c
+	    fi
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" y.tab.h
+	    fi
+	  ;;
+	esac
+    fi
+    if [ ! -f y.tab.h ]; then
+	echo >y.tab.h
+    fi
+    if [ ! -f y.tab.c ]; then
+	echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+	case "$LASTARG" in
+	*.l)
+	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" lex.yy.c
+	    fi
+	  ;;
+	esac
+    fi
+    if [ ! -f lex.yy.c ]; then
+	echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 \`Help2man' package in order for those modifications to take
+	 effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+	file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+    fi
+    if [ -f "$file" ]; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit 1
+    fi
+    ;;
+
+  makeinfo)
+    if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
+       # We have makeinfo, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+    fi
+    touch $file
+    ;;
+
+  tar)
+    shift
+    if test -n "$run"; then
+      echo 1>&2 "ERROR: \`tar' requires --run"
+      exit 1
+    fi
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+	case "$firstarg" in
+	*o*)
+	    firstarg=`echo "$firstarg" | sed s/o//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+	case "$firstarg" in
+	*h*)
+	    firstarg=`echo "$firstarg" | sed s/h//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequirements for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
Index: /branches/rel3/psModules/mkinstalldirs
===================================================================
--- /branches/rel3/psModules/mkinstalldirs	(revision 2163)
+++ /branches/rel3/psModules/mkinstalldirs	(revision 2163)
@@ -0,0 +1,111 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
+
+# process command line arguments
+while test $# -gt 0 ; do
+  case $1 in
+    -h | --help | --h*)         # -h for help
+      echo "$usage" 1>&2
+      exit 0
+      ;;
+    -m)                         # -m PERM arg
+      shift
+      test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+      dirmode=$1
+      shift
+      ;;
+    --)                         # stop option processing
+      shift
+      break
+      ;;
+    -*)                         # unknown option
+      echo "$usage" 1>&2
+      exit 1
+      ;;
+    *)                          # first non-opt arg
+      break
+      ;;
+  esac
+done
+
+for file
+do
+  if test -d "$file"; then
+    shift
+  else
+    break
+  fi
+done
+
+case $# in
+  0) exit 0 ;;
+esac
+
+case $dirmode in
+  '')
+    if mkdir -p -- . 2>/dev/null; then
+      echo "mkdir -p -- $*"
+      exec mkdir -p -- "$@"
+    fi
+    ;;
+  *)
+    if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
+      echo "mkdir -m $dirmode -p -- $*"
+      exec mkdir -m "$dirmode" -p -- "$@"
+    fi
+    ;;
+esac
+
+for file
+do
+  set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+  shift
+
+  pathcomp=
+  for d
+  do
+    pathcomp="$pathcomp$d"
+    case $pathcomp in
+      -*) pathcomp=./$pathcomp ;;
+    esac
+
+    if test ! -d "$pathcomp"; then
+      echo "mkdir $pathcomp"
+
+      mkdir "$pathcomp" || lasterr=$?
+
+      if test ! -d "$pathcomp"; then
+  	errstatus=$lasterr
+      else
+  	if test ! -z "$dirmode"; then
+	  echo "chmod $dirmode $pathcomp"
+    	  lasterr=""
+  	  chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+  	  if test ! -z "$lasterr"; then
+  	    errstatus=$lasterr
+  	  fi
+  	fi
+      fi
+    fi
+
+    pathcomp="$pathcomp/"
+  done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# End:
+# mkinstalldirs ends here
Index: /branches/rel3/psModules/psmodule.kdevelop
===================================================================
--- /branches/rel3/psModules/psmodule.kdevelop	(revision 2163)
+++ /branches/rel3/psModules/psmodule.kdevelop	(revision 2163)
@@ -0,0 +1,180 @@
+<?xml version = '1.0'?>
+<kdevelop>
+  <general>
+    <author>Robert Daniel DeSonia</author>
+    <email>desonia@mhpcc.hawaii.edu</email>
+    <version>0.1</version>
+    <projectmanagement>KDevAutoProject</projectmanagement>
+    <primarylanguage>C</primarylanguage>
+    <keywords>
+      <keyword>C</keyword>
+      <keyword>Code</keyword>
+    </keywords>
+    <projectdirectory>.</projectdirectory>
+    <absoluteprojectpath>false</absoluteprojectpath>
+    <description/>
+    <ignoreparts/>
+    <secondaryLanguages/>
+  </general>
+  <kdevautoproject>
+    <general>
+      <activetarget>src/psmodule</activetarget>
+      <useconfiguration>debug</useconfiguration>
+    </general>
+    <run>
+      <mainprogram>src/tst_pmFlatField</mainprogram>
+      <terminal>true</terminal>
+      <directoryradio>executable</directoryradio>
+      <customdirectory>/</customdirectory>
+      <programargs/>
+      <autocompile>true</autocompile>
+      <envvars/>
+    </run>
+    <configurations>
+      <optimized>
+        <builddir>optimized</builddir>
+        <ccompiler>kdevgccoptions</ccompiler>
+        <cxxcompiler>kdevgppoptions</cxxcompiler>
+        <f77compiler>kdevg77options</f77compiler>
+        <cflags>-O2 -g0</cflags>
+      </optimized>
+      <debug>
+        <configargs>--enable-debug=full</configargs>
+        <builddir>debug</builddir>
+        <ccompiler>kdevgccoptions</ccompiler>
+        <cxxcompiler>kdevgppoptions</cxxcompiler>
+        <f77compiler>kdevg77options</f77compiler>
+        <cflags>-O0 -g3</cflags>
+      </debug>
+    </configurations>
+    <make>
+      <envvars>
+        <envvar value="1" name="WANT_AUTOCONF_2_5" />
+        <envvar value="1" name="WANT_AUTOMAKE_1_6" />
+      </envvars>
+      <abortonerror>false</abortonerror>
+      <numberofjobs>1</numberofjobs>
+      <dontact>false</dontact>
+      <makebin/>
+    </make>
+  </kdevautoproject>
+  <kdevdoctreeview>
+    <ignoretocs>
+      <toc>ada</toc>
+      <toc>ada_bugs_gcc</toc>
+      <toc>bash</toc>
+      <toc>bash_bugs</toc>
+      <toc>clanlib</toc>
+      <toc>w3c-dom-level2-html</toc>
+      <toc>fortran_bugs_gcc</toc>
+      <toc>gnome1</toc>
+      <toc>gnustep</toc>
+      <toc>gtk</toc>
+      <toc>gtk_bugs</toc>
+      <toc>haskell</toc>
+      <toc>haskell_bugs_ghc</toc>
+      <toc>java_bugs_gcc</toc>
+      <toc>java_bugs_sun</toc>
+      <toc>kde2book</toc>
+      <toc>libstdc++</toc>
+      <toc>opengl</toc>
+      <toc>pascal_bugs_fp</toc>
+      <toc>php</toc>
+      <toc>php_bugs</toc>
+      <toc>perl</toc>
+      <toc>perl_bugs</toc>
+      <toc>python</toc>
+      <toc>python_bugs</toc>
+      <toc>qt-kdev3</toc>
+      <toc>ruby</toc>
+      <toc>ruby_bugs</toc>
+      <toc>sdl</toc>
+      <toc>stl</toc>
+      <toc>w3c-svg</toc>
+      <toc>sw</toc>
+      <toc>w3c-uaag10</toc>
+      <toc>wxwidgets_bugs</toc>
+    </ignoretocs>
+    <ignoreqt_xml>
+      <toc>Guide to the Qt Translation Tools</toc>
+      <toc>Qt Assistant Manual</toc>
+      <toc>Qt Designer Manual</toc>
+      <toc>Qt Reference Documentation</toc>
+      <toc>qmake User Guide</toc>
+    </ignoreqt_xml>
+    <ignoredoxygen>
+      <toc>KDE Libraries (Doxygen)</toc>
+    </ignoredoxygen>
+    <projectdoc>
+      <userdocDir>html/</userdocDir>
+      <apidocDir>html/</apidocDir>
+    </projectdoc>
+    <ignorekdocs/>
+    <ignoredevhelp/>
+  </kdevdoctreeview>
+  <kdevfilecreate>
+    <filetypes/>
+    <useglobaltypes>
+      <type ext="c" />
+      <type ext="h" />
+    </useglobaltypes>
+  </kdevfilecreate>
+  <kdevfileview>
+    <groups>
+      <group pattern="*.h" name="Header files" />
+      <group pattern="*.c" name="Source files" />
+      <hidenonprojectfiles>false</hidenonprojectfiles>
+      <hidenonlocation>false</hidenonlocation>
+    </groups>
+    <tree>
+      <hidepatterns>*.o,*.lo,CVS</hidepatterns>
+      <hidenonprojectfiles>false</hidenonprojectfiles>
+      <showvcsfields>false</showvcsfields>
+    </tree>
+  </kdevfileview>
+  <kdevcppsupport>
+    <references/>
+    <codecompletion>
+      <includeGlobalFunctions>true</includeGlobalFunctions>
+      <includeTypes>true</includeTypes>
+      <includeEnums>true</includeEnums>
+      <includeTypedefs>false</includeTypedefs>
+      <automaticCodeCompletion>true</automaticCodeCompletion>
+      <automaticArgumentsHint>true</automaticArgumentsHint>
+      <automaticHeaderCompletion>true</automaticHeaderCompletion>
+      <codeCompletionDelay>250</codeCompletionDelay>
+      <argumentsHintDelay>400</argumentsHintDelay>
+      <headerCompletionDelay>250</headerCompletionDelay>
+    </codecompletion>
+  </kdevcppsupport>
+  <cppsupportpart>
+    <filetemplates>
+      <interfacesuffix>.h</interfacesuffix>
+      <implementationsuffix>.cpp</implementationsuffix>
+    </filetemplates>
+  </cppsupportpart>
+  <kdevdebugger>
+    <general>
+      <programargs/>
+      <gdbpath/>
+      <dbgshell/>
+      <configGdbScript/>
+      <runShellScript/>
+      <runGdbScript/>
+      <breakonloadinglibs>true</breakonloadinglibs>
+      <separatetty>false</separatetty>
+      <floatingtoolbar>false</floatingtoolbar>
+    </general>
+    <display>
+      <staticmembers>false</staticmembers>
+      <demanglenames>true</demanglenames>
+    </display>
+  </kdevdebugger>
+  <kdevcvsservice>
+    <recursivewhenupdate>true</recursivewhenupdate>
+    <prunedirswhenupdate>true</prunedirswhenupdate>
+    <createdirswhenupdate>true</createdirswhenupdate>
+    <recursivewhencommitremove>true</recursivewhencommitremove>
+    <revertoptions>-C</revertoptions>
+  </kdevcvsservice>
+</kdevelop>
Index: /branches/rel3/psModules/psmodule.kdevses
===================================================================
--- /branches/rel3/psModules/psmodule.kdevses	(revision 2163)
+++ /branches/rel3/psModules/psmodule.kdevses	(revision 2163)
@@ -0,0 +1,26 @@
+<?xml version = '1.0' encoding = 'UTF-8'?>
+<!DOCTYPE KDevPrjSession>
+<KDevPrjSession>
+ <DocsAndViews NumberOfDocuments="1" >
+  <Doc0 NumberOfViews="1" URL="file:/home/desonia/psModule/src/Doxyfile" >
+   <View0 line="25" Type="???" >
+    <AdditionalSettings Top="2" Width="1268" Attach="1" Height="1027" Left="2" MinMaxMode="0" />
+   </View0>
+  </Doc0>
+ </DocsAndViews>
+ <pluginList>
+  <kdevbookmarks>
+   <bookmarks/>
+  </kdevbookmarks>
+  <kdevsubversion>
+   <subversion recurseresolve="1" recurserelocate="1" recursemerge="1" recursecommit="1" base="" recursepropget="1" recurseswitch="1" recurseupdate="1" recursepropset="1" recursediff="1" recurserevert="1" forcemove="1" recursecheckout="1" forceremove="1" recurseadd="1" recurseproplist="1" forcemerge="1" />
+  </kdevsubversion>
+  <kdevvalgrind>
+   <executable path="" params="" />
+   <valgrind path="" params="" />
+  </kdevvalgrind>
+  <kdevdebugger>
+   <breakpointList/>
+  </kdevdebugger>
+ </pluginList>
+</KDevPrjSession>
Index: /branches/rel3/psModules/src/.cvsignore
===================================================================
--- /branches/rel3/psModules/src/.cvsignore	(revision 2163)
+++ /branches/rel3/psModules/src/.cvsignore	(revision 2163)
@@ -0,0 +1,4 @@
+.deps
+Makefile
+config.h
+stamp-h1
Index: /branches/rel3/psModules/src/Doxyfile
===================================================================
--- /branches/rel3/psModules/src/Doxyfile	(revision 2163)
+++ /branches/rel3/psModules/src/Doxyfile	(revision 2163)
@@ -0,0 +1,1080 @@
+# Doxyfile 1.3.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "Pan-STARRS Module Library"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER         = V1.0-R3
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = ../docs
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch,
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en
+# (Japanese with English messages), Korean, Norwegian, Polish, Portuguese,
+# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC    = YES
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
+# members of a class in the documentation of that class as if those members were
+# ordinary class members. Constructors, destructors and assignment operators of
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH        =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explict @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP         = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# reimplements.
+
+INHERIT_DOCS           = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING            = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = DoxygenLog
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = . \
+                         mainpage.dox
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
+# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc
+
+FILE_PATTERNS          = *.h *.dox
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories 
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories.
+
+EXCLUDE_PATTERNS       = *_wrap.c
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.
+
+INPUT_FILTER           = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output dir.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = YES
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 10
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = YES
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = times
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimised for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assigments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = YES
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED             = DOXYGEN
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse the 
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off. Note that this 
+# option is superceded by the HAVE_DOT option below. This is only a fallback. It is 
+# recommended to install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similiar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes that 
+# lay further from the root node will be omitted. Note that setting this option to 
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also 
+# note that a graph may be further truncated if the graph's image dimensions are 
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). 
+# If 0 is used for the depth value (the default), the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
+
Index: /branches/rel3/psModules/src/Makefile.am
===================================================================
--- /branches/rel3/psModules/src/Makefile.am	(revision 2163)
+++ /branches/rel3/psModules/src/Makefile.am	(revision 2163)
@@ -0,0 +1,5 @@
+lib_LIBRARIES = libpsmodule.a
+
+libpsmodule_a_SOURCES = pmFlatField.c pmMaskBadPixels.c pmSubtractBias.c psTest.c pmSubtractBias.c pmNonLinear.c
+libpsmodule_a_HEADERS = pmFlatField.h pmMaskBadPixels.h pmSubtractBias.h psTest.h pmSubtractBias.h pmNonLinear.h
+libpsmodule_adir = $(includedir)
Index: /branches/rel3/psModules/src/Makefile.in
===================================================================
--- /branches/rel3/psModules/src/Makefile.in	(revision 2163)
+++ /branches/rel3/psModules/src/Makefile.in	(revision 2163)
@@ -0,0 +1,504 @@
+# Makefile.in generated by automake 1.8.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+SOURCES = $(libpsmodule_a_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+subdir = src
+DIST_COMMON = $(libpsmodule_a_HEADERS) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in $(srcdir)/config.h.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+ARFLAGS = cru
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libpsmodule_adir)"
+libLIBRARIES_INSTALL = $(INSTALL_DATA)
+LIBRARIES = $(lib_LIBRARIES)
+libpsmodule_a_AR = $(AR) $(ARFLAGS)
+libpsmodule_a_LIBADD =
+am_libpsmodule_a_OBJECTS = pmFlatField.$(OBJEXT) \
+	pmMaskBadPixels.$(OBJEXT) pmSubtractBias.$(OBJEXT) \
+	psTest.$(OBJEXT) pmSubtractBias.$(OBJEXT) \
+	pmNonLinear.$(OBJEXT)
+libpsmodule_a_OBJECTS = $(am_libpsmodule_a_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/pmFlatField.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/pmMaskBadPixels.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/pmNonLinear.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/pmSubtractBias.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/psTest.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libpsmodule_a_SOURCES)
+DIST_SOURCES = $(libpsmodule_a_SOURCES)
+libpsmodule_aHEADERS_INSTALL = $(INSTALL_HEADER)
+HEADERS = $(libpsmodule_a_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GSL_CONFIG = @GSL_CONFIG@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+lib_LIBRARIES = libpsmodule.a
+libpsmodule_a_SOURCES = pmFlatField.c pmMaskBadPixels.c pmSubtractBias.c psTest.c pmSubtractBias.c pmNonLinear.c
+libpsmodule_a_HEADERS = pmFlatField.h pmMaskBadPixels.h pmSubtractBias.h psTest.h pmSubtractBias.h pmNonLinear.h
+libpsmodule_adir = $(includedir)
+all: config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  src/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu  src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+config.h: stamp-h1
+	@if test ! -f $@; then \
+	  rm -f stamp-h1; \
+	  $(MAKE) stamp-h1; \
+	else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+	@rm -f stamp-h1
+	cd $(top_builddir) && $(SHELL) ./config.status src/config.h
+$(srcdir)/config.h.in:  $(am__configure_deps) 
+	cd $(top_srcdir) && $(AUTOHEADER)
+	rm -f stamp-h1
+	touch $@
+
+distclean-hdr:
+	-rm -f config.h stamp-h1
+install-libLIBRARIES: $(lib_LIBRARIES)
+	@$(NORMAL_INSTALL)
+	test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
+	@list='$(lib_LIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    f="`echo $$p | sed -e 's|^.*/||'`"; \
+	    echo " $(libLIBRARIES_INSTALL) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
+	    $(libLIBRARIES_INSTALL) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
+	  else :; fi; \
+	done
+	@$(POST_INSTALL)
+	@list='$(lib_LIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    p="`echo $$p | sed -e 's|^.*/||'`"; \
+	    echo " $(RANLIB) '$(DESTDIR)$(libdir)/$$p'"; \
+	    $(RANLIB) "$(DESTDIR)$(libdir)/$$p"; \
+	  else :; fi; \
+	done
+
+uninstall-libLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(lib_LIBRARIES)'; for p in $$list; do \
+	  p="`echo $$p | sed -e 's|^.*/||'`"; \
+	  echo " rm -f '$(DESTDIR)$(libdir)/$$p'"; \
+	  rm -f "$(DESTDIR)$(libdir)/$$p"; \
+	done
+
+clean-libLIBRARIES:
+	-test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
+libpsmodule.a: $(libpsmodule_a_OBJECTS) $(libpsmodule_a_DEPENDENCIES) 
+	-rm -f libpsmodule.a
+	$(libpsmodule_a_AR) libpsmodule.a $(libpsmodule_a_OBJECTS) $(libpsmodule_a_LIBADD)
+	$(RANLIB) libpsmodule.a
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmFlatField.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmMaskBadPixels.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmNonLinear.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pmSubtractBias.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psTest.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool
+uninstall-info-am:
+install-libpsmodule_aHEADERS: $(libpsmodule_a_HEADERS)
+	@$(NORMAL_INSTALL)
+	test -z "$(libpsmodule_adir)" || $(mkdir_p) "$(DESTDIR)$(libpsmodule_adir)"
+	@list='$(libpsmodule_a_HEADERS)'; for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  f="`echo $$p | sed -e 's|^.*/||'`"; \
+	  echo " $(libpsmodule_aHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(libpsmodule_adir)/$$f'"; \
+	  $(libpsmodule_aHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(libpsmodule_adir)/$$f"; \
+	done
+
+uninstall-libpsmodule_aHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(libpsmodule_a_HEADERS)'; for p in $$list; do \
+	  f="`echo $$p | sed -e 's|^.*/||'`"; \
+	  echo " rm -f '$(DESTDIR)$(libpsmodule_adir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(libpsmodule_adir)/$$f"; \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(ETAGS_ARGS)$$tags$$unique" \
+	  || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	     $$tags $$unique
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkdir_p) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES) $(HEADERS) config.h
+installdirs:
+	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libpsmodule_adir)"; do \
+	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libLIBRARIES clean-libtool \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-hdr distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-libpsmodule_aHEADERS
+
+install-exec-am: install-libLIBRARIES
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-libLIBRARIES \
+	uninstall-libpsmodule_aHEADERS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-libLIBRARIES clean-libtool ctags distclean \
+	distclean-compile distclean-generic distclean-hdr \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-exec install-exec-am install-info \
+	install-info-am install-libLIBRARIES \
+	install-libpsmodule_aHEADERS install-man install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags uninstall uninstall-am uninstall-info-am \
+	uninstall-libLIBRARIES uninstall-libpsmodule_aHEADERS
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
Index: /branches/rel3/psModules/src/config.h.in
===================================================================
--- /branches/rel3/psModules/src/config.h.in	(revision 2163)
+++ /branches/rel3/psModules/src/config.h.in	(revision 2163)
@@ -0,0 +1,73 @@
+/* src/config.h.in.  Generated from configure.in by autoheader.  */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `cfitsio' library (-lcfitsio). */
+#undef HAVE_LIBCFITSIO
+
+/* Define to 1 if you have the `fftw3f' library (-lfftw3f). */
+#undef HAVE_LIBFFTW3F
+
+/* Define to 1 if you have the `gsl' library (-lgsl). */
+#undef HAVE_LIBGSL
+
+/* Define to 1 if you have the `gslcblas' library (-lgslcblas). */
+#undef HAVE_LIBGSLCBLAS
+
+/* Define to 1 if you have the `pslib' library (-lpslib). */
+#undef HAVE_LIBPSLIB
+
+/* Define to 1 if you have the `sla' library (-lsla). */
+#undef HAVE_LIBSLA
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
Index: /branches/rel3/psModules/src/mainpage.dox
===================================================================
--- /branches/rel3/psModules/src/mainpage.dox	(revision 2163)
+++ /branches/rel3/psModules/src/mainpage.dox	(revision 2163)
@@ -0,0 +1,125 @@
+/** @mainpage psModule Image Processing Library
+
+
+@section intro Introduction
+This library contains the Pan-STARRS Image Processing Pipeline (IPP) modules (psModule). These modules
+use the functionality of the Pan-STARRS Library (psLib) to perform more complex tasks associated with image
+processing. Modules were constructed to support each of the required processing stages and are listed according
+to the particular processing stage for which they will primarily be used. To preserve namespace, globally-visible
+structures and functions are prefixed with pm, an abbreviation for Pan-STARRS Modules.
+
+Modules in this release include:
+
+ - Subtract bias (pmSubtractBias)
+ - Correct for non-linearity (pmNonLinear)
+ - Flat-field (pmFlatField)
+ - Mask bad pixels (pmMaskBadPixels)
+
+
+The installed code for psModule consists of header files and a static binary library (libpsmodule.a).
+
+@section extinstall Required 3rd Party Libraries
+
+Before building psLib from source, several 3rd party software libraries must
+be installed. These include:
+ - Pan-STARRS Library (psLib)
+     - Available from the Maui High Performance Computiong Center (MHPCC) at https://mhpcc.pan-starrs.org/code/releases
+     - Compatibility tested with rel3
+ - GNU Scientific Library (GSL)
+     - Available at http://www.gnu.org/software/gsl
+     - Compatibility tested with version is 1.4
+ - Fastest Fourier Transform in the West (FFTW), version 3
+     - Available at http://www.fftw.org
+     - Compatibility tested with version is 3.0.1
+ - C Flexible Image Transport System Input output (CFITSIO), version 2.480 or later
+     - Available at http://heasarc.gsfc.nasa.gov/docs/software/fitsio
+     - Compatibility tested with version is 2.490
+     - Versions earlier than 2.480 will not work as new functionality introduced in 2.480 is exercised
+ - Doxygen Documentation System
+     - Available at http://www.doxygen.org
+     - Compatibility tested with version 1.3.6
+     - The optional companion package, GraphViz (a.k.a., the 'dot' command), is recommended to enable header-file dependency diagrams
+ - SLALIB
+     - Available at http://star-www.rl.ac.uk/
+     - Compatibility tested with package version number 2.4-12
+
+We recommend using the particular versions listed as compatibility tested, as
+that is the only versions of the external libraries tested to work well with psLib
+and psModule.  Though it is quite possible that later versions of the libraries
+listed will also work, care must be taken when upgrading these libraries to verify
+that its functionality is compatible with the tested version.
+
+@section install How to Build from Source
+
+Tested versions of psModule are put into a tar file and can be downloaded from:
+
+https://mhpcc.pan-starrs.org/code/releases
+
+Though MHPCC recommends using the released packaged tar files descibed above,
+both daily development snapshots and direct CVS access is available.  The daily
+snapshots are available at
+
+https://mhpcc.pan-starrs.org/code/snapshots
+
+These snapshots represents development code as found in CVS on the day
+specified in the filename.  This code set may not be functional, vary in
+testing, etc.  Reasonable efforts are made to ensure that the code does
+actually compile, but given the nature of code development, even that is not
+always the case.  Use snapshots with great caution.
+
+If one has a login account on mhpcc.pan-starrs.org, direct CVS access is
+possible.  Example of the commands required for direct CVS retrieval are
+as follows:
+<pre>
+$ cvs -d:ext:USERNAME@mhpcc.pan-starrs.org:/data/panstarrs/cvsroot co -r RELEASEBRANCH psModule
+</pre>
+where:
+  - USERNAME is your login name on the server
+  - RELEASEBRANCH is the desired release branch, e.g. rel1.
+
+
+@section build How to Build the psModule library.
+
+The psModule library and associated tests are made via the GNU autoconf/automake system.
+
+The source should build using the configure script in the psModule directory.  The
+recommended steps are:
+<pre>
+$ cd psModule
+$ configure --with-psLib=/home/kaiser/psLib (NB: Directory for psLib will vary)
+$ make
+</pre>
+<i>This builds files in psModule/src and psModule/test.</i>
+
+Other configuration options, such as location of other 3rd party libraries, are also available.
+To get a list of options, type the following in the top psModule directory.
+<pre>
+$ configure --help
+</pre>
+
+@section run How to Build and Run Tests
+
+To test the installation, users may execute the unit tests which was automatically built
+when the user performs a make from the psModule directory.
+<pre>
+$ cd psModule/test
+$ ./FullUnitTest
+</pre>
+<i>This executes all test drivers in psModule/test.</i>
+
+@section doc How to Create Code Documentation
+
+Both HTML and man page documentation may be generated from the inline
+documentation embedded in the code using the following commands:
+<pre>
+$ cd psModule/src
+$ doxygen
+</pre>
+<i>This places documentation in psModule/docs.</i>
+
+Also, a prebuilt set of code documentation for both the releases and last
+CVS snapshot can be found at:
+
+https://mhpcc.pan-starrs.org/docs/
+
+*/
Index: /branches/rel3/psModules/src/parseErrorCodes.pl
===================================================================
--- /branches/rel3/psModules/src/parseErrorCodes.pl	(revision 2163)
+++ /branches/rel3/psModules/src/parseErrorCodes.pl	(revision 2163)
@@ -0,0 +1,97 @@
+#!/usr/bin/perl
+
+# Provides functions for handling long command line options
+use Getopt::Long;
+
+my @ErrorCodes        = ();
+my @ErrorDescriptions = ();
+
+my $data = "psErrorCodes.dat";
+
+# Assign variables based on the presence of command line options to the script
+GetOptions(
+    "data=s"  => \$data,
+    "verbose" => \$verbose,
+    "help"    => \$help
+);
+
+if ($help) {
+    print "Usage: parseErrorCodes ", "[--data=$data] ", "[--help] ",
+      "[--verbose] filename [filename ...]\n\n";
+    exit(0);
+}
+
+print "Using data file '$data'\n" if $verbose;
+unless ( open( DATAFILE, "<", $data ) ) {
+    die "Can not open data file $data.";
+}
+
+print "Datafile:\n" if $verbose;
+while (<DATAFILE>) {
+    chop;
+    if (/^\s*\#/) {
+        print "C $_\n" if $verbose;
+    }
+    else {
+        if (/^\s*(\w+)\s+([\%\w].*)/) {
+            my $ErrorCode        = $1;
+            my $ErrorDescription = $2;
+            print "  $ErrorCode: '$ErrorDescription'\n" if $verbose;
+            push( @ErrorCodes,        $ErrorCode );
+            push( @ErrorDescriptions, $ErrorDescription );
+        } else {
+            print "I $_\n" if $verbose;
+        }
+    }
+}
+close(DATAFILE);
+
+my $found = $#ErrorCodes + 1;
+print "\nFound $found error codes.\n" if $verbose;
+
+foreach (@ARGV) {
+    my $filename = $_;
+    my @result   = ();
+
+    die "Failed to open input file"
+      if !open( INFILE, "<", $filename );
+
+    print "\nOutput File:\n" if $verbose;
+    while (<INFILE>) {
+        chop;
+        push( @result, $_ );
+        if (/^\s*\/\/~Start(.*)$/) {
+            $line = $1;
+            for ( $n = 0 ; $n < $found ; $n++ ) {
+                $_ = $line;
+                s/\$1/$ErrorCodes[$n]/g;
+                s/\$2/$ErrorDescriptions[$n]/g;
+                s/\$n/$n/g;
+                push( @result, $_ );
+                print "$_\n" if $verbose;
+            }
+
+            $break = 0;
+            while ( ( $break == 0 ) && ( $_ = <INFILE> ) ) {
+                if (/^\s*\/\/~End/) {
+                    $break = 1;
+                }
+            }
+            chop;
+            push( @result, $_ );
+        }
+    }
+
+    close(INFILE);
+
+    die "Failed to overwrite input file"
+      if !open( OUTFILE, ">", $filename );
+
+    foreach (@result) {
+        print OUTFILE "$_\n";
+        print "$_\n" if $verbose;
+    }
+
+    close(OUTFILE);
+
+}
Index: /branches/rel3/psModules/src/pmFlatField.c
===================================================================
--- /branches/rel3/psModules/src/pmFlatField.c	(revision 2163)
+++ /branches/rel3/psModules/src/pmFlatField.c	(revision 2163)
@@ -0,0 +1,180 @@
+/** @file  pmFlatField.c
+ *
+ *  @brief Given an input image and a flat field image, pmFlatField shall divide the input image by the flat
+ *  field image.
+ *
+ *  The input image, in, and the flat field image, flat, need not be the same size, since the input image may
+ *  already have been trimmed (following overscan subtraction), but the function shall use the offsets in the
+ *  image (in->x0 and in->y0) to determine the appropriate offsets to obtain the correct pixel on the flat
+ *  field. In the event that the flat image is too small (i.e., pixels on the input image refer to pixels
+ *  outside the range of the flat image), the function shall generate an error. Pixels which are negative or
+ *  zero in the flat shall be masked in the input image with the value PM_MASK_FLAT. Negative pixels in the
+ *  flat may be set to zero so that they are treated identically to zeroes. Any pixels masked in the flat
+ *  shall be masked with corresponding values in the output. The function shall not normalize the flat; this
+ *  responsibility is left to the caller. This function is basically equivalent to a divide (with psImageOp),
+ *  but with care for the region that is divided, checking for negative pixels, and copying of the mask from
+ *  the flat to the output.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 23:52:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include<stdio.h>
+#include<math.h>
+#include <string.h>
+
+#include "pslib.h"
+#include "pmFlatField.h"
+#include "pmMaskBadPixels.h"
+#include "pmFlatFieldErrors.h"
+
+
+bool pmFlatField(psReadout *in, const psReadout *flat)
+{
+    int i = 0;
+    int j = 0;
+    int totOffCol = 0;
+    int totOffRow = 0;
+    psElemType inType;
+    psElemType flatType;
+    psElemType maskType;
+    psImage *inImage = NULL;
+    psImage *inMask = NULL;
+    psImage *flatImage = NULL;
+
+
+    // Check for nulls
+    if (in == NULL) {
+        return true;       // Readout may not have data in it
+    } else if(flat==NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmFlatField", PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_pmFlatField_NULL_FLAT_READOUT);
+        return false;
+    }
+
+    inImage = in->image;
+    flatImage = flat->image;
+    if (inImage == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmFlatField", PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_pmFlatField_NULL_INPUT_IMAGE);
+        return false;
+    } else if(flatImage == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmFlatField", PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_pmFlatField_NULL_FLAT_IMAGE);
+        return false;
+    } else if(in->mask == NULL) {
+        in->mask = psImageAlloc(inImage->numCols, inImage->numRows, PS_TYPE_MASK);
+        memset(in->mask->data.V[0], 0, inImage->numCols*inImage->numRows*PSELEMTYPE_SIZEOF(PS_TYPE_MASK));
+    }
+    inMask = in->mask;
+
+    // Check input image and its mask are not larger than flat image
+    if(inImage->numRows>flatImage->numRows || inImage->numCols>flatImage->numCols) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmFlatField", PS_ERR_BAD_PARAMETER_SIZE, true,
+                   PS_ERRORTEXT_pmFlatField_SIZE_INPUT_IMAGE,
+                   inImage->numRows, inImage->numCols, flatImage->numRows, flatImage->numCols);
+        return false;
+    } else if(inMask->numRows>flatImage->numRows || inMask->numCols > flatImage->numCols) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmFlatField", PS_ERR_BAD_PARAMETER_SIZE, true,
+                   PS_ERRORTEXT_pmFlatField_SIZE_MASK_IMAGE,
+                   inMask->numRows, inMask->numCols, flatImage->numRows, flatImage->numCols);
+        return false;
+    }
+
+    // Determine total offset based on image offset with chip offset
+    totOffCol = inImage->col0 + in->col0;
+    totOffRow = inImage->row0 + in->row0;
+
+    // Check that offsets are within image limits
+    if(totOffRow>=flatImage->numRows || totOffCol>=flatImage->numCols) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmFlatField", PS_ERR_BAD_PARAMETER_SIZE, true,
+                   PS_ERRORTEXT_pmFlatField_OFFSET_FLAT_IMAGE,
+                   totOffRow, totOffCol, flatImage->numRows, flatImage->numCols);
+        return false;
+    } else if(totOffRow>=inImage->numRows || totOffCol>=inImage->numCols) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmFlatField", PS_ERR_BAD_PARAMETER_SIZE, true,
+                   PS_ERRORTEXT_pmFlatField_OFFSET_INPUT_IMAGE,
+                   totOffRow, totOffCol, inImage->numRows, inImage->numCols);
+        return false;
+    } else if(totOffRow>=inMask->numRows || totOffCol>=inMask->numCols) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmFlatField", PS_ERR_BAD_PARAMETER_SIZE, true,
+                   PS_ERRORTEXT_pmFlatField_OFFSET_MASK_IMAGE,
+                   totOffRow, totOffCol, inMask->numRows, inMask->numCols);
+        return false;
+    }
+
+    // Check for incorrect types
+    inType = inImage->type.type;
+    flatType = flatImage->type.type;
+    maskType = inMask->type.type;
+    if(PS_IS_PSELEMTYPE_COMPLEX(inType)) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmFlatField", PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_pmFlatField_TYPE_INPUT_IMAGE,
+                   inType);
+        return false;
+    } else if(PS_IS_PSELEMTYPE_COMPLEX(flatType)) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmFlatField", PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_pmFlatField_TYPE_FLAT_IMAGE,
+                   flatType);
+        return false;
+    } else if(maskType != PS_TYPE_MASK) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmFlatField", PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_pmFlatField_TYPE_MASK_IMAGE,
+                   maskType);
+        return false;
+    } else if(inType != flatType) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmFlatField", PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_pmFlatField_TYPE_MISMATCH,
+                   inType, flatType);
+        return false;
+    }
+
+    // Macro for all PS types
+    #define PM_FLAT_DIVISION(TYPE)                                                                           \
+case PS_TYPE_##TYPE:                                                                                         \
+    /* Per Eugene's request, use two sets of loops: first to fill mask, second to avoid div with bad pix */  \
+    for(j = totOffRow; j < inImage->numRows; j++) {                                                          \
+        for(i = totOffCol; i < inImage->numCols; i++) {                                                      \
+            if(flatImage->data.TYPE[j][i] <= 0.0) {                                                          \
+                /* Negative or zero flat pixels shall be masked in input image as  PM_MASK_FLAT */           \
+                inMask->data.PS_TYPE_MASK_DATA[j][i] |= PM_MASK_FLAT;                                        \
+            }                                                                                                \
+        }                                                                                                    \
+    }                                                                                                        \
+    for(j = totOffRow; j < inImage->numRows; j++) {                                                          \
+        for(i = totOffCol; i < inImage->numCols; i++) {                                                      \
+            if(!inMask->data.PS_TYPE_MASK_DATA[j][i]) {                                                      \
+                /* Module shall divide the input image by the flat-fielded image */                          \
+                inImage->data.TYPE[j][i] /= flatImage->data.TYPE[j][i];                                      \
+            }                                                                                                \
+        }                                                                                                    \
+    }                                                                                                        \
+    break;
+
+    switch(inType) {
+        PM_FLAT_DIVISION(U8);
+        PM_FLAT_DIVISION(U16);
+        PM_FLAT_DIVISION(U32);
+        PM_FLAT_DIVISION(U64);
+        PM_FLAT_DIVISION(S8);
+        PM_FLAT_DIVISION(S16);
+        PM_FLAT_DIVISION(S32);
+        PM_FLAT_DIVISION(S64);
+        PM_FLAT_DIVISION(F32);
+        PM_FLAT_DIVISION(F64);
+    default:
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmFlatField", PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_pmFlatField_TYPE_UNSUPPORTED,
+                   inType);
+    }
+
+    return true;
+}
Index: /branches/rel3/psModules/src/pmFlatField.h
===================================================================
--- /branches/rel3/psModules/src/pmFlatField.h	(revision 2163)
+++ /branches/rel3/psModules/src/pmFlatField.h	(revision 2163)
@@ -0,0 +1,37 @@
+/** @file  pmFlatField.h
+ *
+ *  @brief Given an input image and a flat field image, pmFlatField shall divide the input image by the flat
+ *  field image.
+ *
+ *  The input image, in, and the flat field image, flat, need not be the same size, since the input image may
+ *  already have been trimmed (following overscan subtraction), but the function shall use the offsets in the
+ *  image (in->x0 and in->y0) to determine the appropriate offsets to obtain the correct pixel on the flat
+ *  field. In the event that the flat image is too small (i.e., pixels on the input image refer to pixels
+ *  outside the range of the flat image), the function shall generate an error. Pixels which are negative or
+ *  zero in the flat shall be masked in the input image with the value PM_MASK_FLAT. Negative pixels in the
+ *  flat may be set to zero so that they are treated identically to zeroes. Any pixels masked in the flat
+ *  shall be masked with corresponding values in the output. The function shall not normalize the flat; this
+ *  responsibility is left to the caller. This function is basically equivalent to a divide (with psImageOp),
+ *  but with care for the region that is divided, checking for negative pixels, and copying of the mask from
+ *  the flat to the output.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-22 19:58:57 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+/** Execute flat field module.
+ *
+ *  Given an input image and a flat-field image, pmFlatField shall divide the input image by the flat field
+ *  image.
+ *
+ *  @return  bool: True or false for success or failure
+ */
+bool pmFlatField(
+    psReadout *in,          ///< Redout with input image and mask
+    const psReadout *flat   ///< Readout with flat image
+);
+
Index: /branches/rel3/psModules/src/pmFlatFieldErrors.dat
===================================================================
--- /branches/rel3/psModules/src/pmFlatFieldErrors.dat	(revision 2163)
+++ /branches/rel3/psModules/src/pmFlatFieldErrors.dat	(revision 2163)
@@ -0,0 +1,22 @@
+#
+#  This file is used to generate pmFlatFieldErrors.h content
+#
+#  Format is:
+#  ERRORNAME(one word)    ERRORTEXT
+#
+#  N.B. in code, the ERRORNAME appears as PS_ERRORTEXT_ERRORNAME
+####################################################################
+#
+pmFlatField_NULL_FLAT_READOUT          Null not allowed for flat readout.
+pmFlatField_NULL_INPUT_IMAGE           Null not allowed for input image.
+pmFlatField_NULL_FLAT_IMAGE            Null not allowed for flat image.
+pmFlatField_SIZE_INPUT_IMAGE           Input image size exceeds that of flat image: (%d, %d) vs (%d, %d)
+pmFlatField_SIZE_MASK_IMAGE            Input image mask size exceeds that of flat image: (%d, %d) vs (%d, %d)
+pmFlatField_OFFSET_FLAT_IMAGE          Total offset >= flat image size: (%d, %d) vs (%d, %d)
+pmFlatField_OFFSET_INPUT_IMAGE         Total offset >= input image: (%d, %d) vs (%d, %d)
+pmFlatField_OFFSET_MASK_IMAGE          Total offset >= input image mask: (%d, %d) vs (%d, %d)
+pmFlatField_TYPE_INPUT_IMAGE           Complex types not allowed for input image. Type: %d
+pmFlatField_TYPE_FLAT_IMAGE            Complex types not allowed for flat image. Type: %d
+pmFlatField_TYPE_MASK_IMAGE            Mask must be PS_TYPE_MASK type. Type: %d
+pmFlatField_TYPE_MISMATCH              Input and flat image types differ: (%d vs %d)
+pmFlatField_TYPE_UNSUPPORTED           Unsupported image datatype. Type: %d
Index: /branches/rel3/psModules/src/pmFlatFieldErrors.h
===================================================================
--- /branches/rel3/psModules/src/pmFlatFieldErrors.h	(revision 2163)
+++ /branches/rel3/psModules/src/pmFlatFieldErrors.h	(revision 2163)
@@ -0,0 +1,47 @@
+/** @file  pmFlatFieldErrors.h
+ *
+ *  @brief Contains the error text for the flat field module
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 18:15:44 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PM_FLATFIELD_ERRORS_H
+#define PM_FLATFIELD_ERRORS_H
+
+/* N.B., lines between '//~Start' and '//~End' are automatic generated from
+ * the template following the '//~Start'.  The template is used to generate
+ * the other lines by, for each error text in psDataManipErrors.dat, the following
+ * substitutions are made:
+ *     $1  The error text macro name (first word in the psFlatFieldErrors.h lines)
+ *     $2  The error text (rest of the line in psFlatFieldErrors.h)
+ *     $n  The order of the source line in psFlatFieldErrors.h (comments excluded)
+ *
+ * DO NOT EDIT THE LINES BETWEEN //~Start and //~End!  ANY CHANGES WILL BE OVERWRITTEN.
+ */
+
+#define PS_ERRORNAME_DOMAIN "psModule.src."
+
+//~Start #define PS_ERRORTEXT_$1 "$2"
+#define PS_ERRORTEXT_pmFlatField_NULL_FLAT_READOUT "Null not allowed for flat readout."
+#define PS_ERRORTEXT_pmFlatField_NULL_INPUT_IMAGE "Null not allowed for input image."
+#define PS_ERRORTEXT_pmFlatField_NULL_FLAT_IMAGE "Null not allowed for flat image."
+#define PS_ERRORTEXT_pmFlatField_SIZE_INPUT_IMAGE "Input image size exceeds that of flat image: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmFlatField_SIZE_MASK_IMAGE "Input image mask size exceeds that of flat image: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmFlatField_OFFSET_FLAT_IMAGE "Total offset >= flat image size: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmFlatField_OFFSET_INPUT_IMAGE "Total offset >= input image: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmFlatField_OFFSET_MASK_IMAGE "Total offset >= input image mask: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmFlatField_TYPE_INPUT_IMAGE "Complex types not allowed for input image. Type: %d"
+#define PS_ERRORTEXT_pmFlatField_TYPE_FLAT_IMAGE "Complex types not allowed for flat image. Type: %d"
+#define PS_ERRORTEXT_pmFlatField_TYPE_MASK_IMAGE "Mask must be PS_TYPE_MASK type. Type: %d"
+#define PS_ERRORTEXT_pmFlatField_TYPE_MISMATCH "Input and flat image types differ: (%d vs %d)"
+#define PS_ERRORTEXT_pmFlatField_TYPE_UNSUPPORTED "Unsupported image datatype. Type: %d"
+//~End
+
+#endif
Index: /branches/rel3/psModules/src/pmMaskBadPixels.c
===================================================================
--- /branches/rel3/psModules/src/pmMaskBadPixels.c	(revision 2163)
+++ /branches/rel3/psModules/src/pmMaskBadPixels.c	(revision 2163)
@@ -0,0 +1,183 @@
+/** @file  pmMaskBadPixels.c
+ *
+ *  @brief Given an input image, a bad pixel mask, a corresponding value in the bad pixel mask to mask, a
+ *  saturation level, and a growing radius, mask in the input image those pixels in the bad pixel mask that
+ *  match the value to mask.
+ *
+ *  Given an input image, in, a bad pixel mask, a corresponding value in the bad pixel mask to mask in the
+ * input image, maskVal, a saturation level, and a growing radius, pmMaskBadPixels shall mask in the input
+ * image those pixels in the bad pixel mask that match the value to mask. Note that the input image, in, is
+ * modified in-place. All pixels in the mask which satisfy the maskVal shall have their corresponding pixels
+ * masked in the input image, in. All pixels which satisfy the growVal shall have their corresponding
+ * pixels, along with all pixels within the grow radius masked. Pixels which have flux greater than sat shall
+ * also be masked, but not grown. Note that the input image, in, and the mask need not be the same size, since
+ * the input image may already have been trimmed (following overscan subtraction), but the function shall use
+ * the offsets in the image (in->x0 and in->y0) to determine the appropriate offsets to obtain the correct
+ * pixel on the mask. In the event that the mask image is too small (i.e., pixels on the input image refer to
+ * pixels outside the range of the mask image), the function shall generate an error.
+ 
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 23:52:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include<stdio.h>
+#include<math.h>
+#include<string.h>
+
+#include "pmMaskBadPixels.h"
+#include "pmMaskBadPixelsErrors.h"
+
+bool pmMaskBadPixels(psReadout *in, const psImage *mask, unsigned int maskVal, float sat,
+                     unsigned int growVal, int grow)
+{
+    int i = 0;
+    int j = 0;
+    int jj = 0;
+    int ii = 0;
+    int rRound = 0;
+    int rowMin = 0;
+    int rowMax = 0;
+    int colMin = 0;
+    int colMax = 0;
+    int totOffCol = 0;
+    int totOffRow = 0;
+    float r = 0.0f;
+    psElemType inType;
+    psElemType maskType;
+    psImage *inImage = NULL;
+    psImage *inMask = NULL;
+
+
+    // Check for nulls
+    if (in == NULL) {
+        return true;   // Readout may not have data in it
+    } else if(mask==NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmMaskBadPixels", PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_pmMaskBadPixels_NULL_MASK_IMAGE);
+        return false;
+    }
+
+    inImage = in->image;
+    if (inImage == NULL) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmMaskBadPixels", PS_ERR_BAD_PARAMETER_NULL, true,
+                   PS_ERRORTEXT_pmMaskBadPixels_NULL_INPUT_IMAGE);
+        return false;
+    } else if(in->mask == NULL) {
+        in->mask = psImageAlloc(inImage->numCols, inImage->numRows, PS_TYPE_MASK);
+        memset(in->mask->data.V[0], 0, inImage->numCols*inImage->numRows*PSELEMTYPE_SIZEOF(PS_TYPE_MASK));
+    }
+    inMask = in->mask;
+
+    // Check input image and its mask are not larger than mask
+    if(inImage->numRows > mask->numRows || inImage->numCols > mask->numCols) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmMaskBadPixels", PS_ERR_BAD_PARAMETER_SIZE, true,
+                   PS_ERRORTEXT_pmMaskBadPixels_SIZE_INPUT_IMAGE,
+                   inImage->numRows, inImage->numCols, mask->numRows, mask->numCols);
+        return false;
+    } else if(inMask->numRows>mask->numRows || inMask->numCols>mask->numCols) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmMaskBadPixels", PS_ERR_BAD_PARAMETER_SIZE, true,
+                   PS_ERRORTEXT_pmMaskBadPixels_SIZE_MASK_IMAGE,
+                   inMask->numRows, inMask->numCols, mask->numRows, mask->numCols);
+        return false;
+    }
+
+    // Determine total offset based on image offset with chip offset
+    totOffCol = inImage->col0 + in->col0;
+    totOffRow = inImage->row0 + in->row0;
+
+    // Check that offsets are within image limits
+    if(totOffRow>=mask->numRows || totOffCol>=mask->numCols) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmMaskBadPixels", PS_ERR_BAD_PARAMETER_SIZE, true,
+                   PS_ERRORTEXT_pmMaskBadPixels_OFFSET_MASK_IMAGE,
+                   totOffRow, totOffCol, mask->numRows, mask->numCols);
+        return false;
+    } else if(totOffRow>=inImage->numRows || totOffCol>=inImage->numCols) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmMaskBadPixels", PS_ERR_BAD_PARAMETER_SIZE, true,
+                   PS_ERRORTEXT_pmMaskBadPixels_OFFSET_INPUT_IMAGE,
+                   totOffRow, totOffCol, inImage->numRows, inImage->numCols);
+        return false;
+    } else if(totOffRow>=inMask->numRows || totOffCol>=inMask->numCols) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmMaskBadPixels", PS_ERR_BAD_PARAMETER_SIZE, true,
+                   PS_ERRORTEXT_pmMaskBadPixels_OFFSET_INPUT_IMAGE_MASK,
+                   totOffRow, totOffCol, inMask->numRows, inMask->numCols);
+        return false;
+    }
+
+    // Check for incorrect types
+    inType = inImage->type.type;
+    maskType = mask->type.type;
+    if(PS_IS_PSELEMTYPE_COMPLEX(inType)) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmMaskBadPixels", PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_pmMaskBadPixels_TYPE_INPUT_IMAGE,
+                   inType);
+        return false;
+    } else if(maskType!=PS_TYPE_MASK) {
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmMaskBadPixels", PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_pmMaskBadPixels_TYPE_MASK_IMAGE,
+                   maskType);
+        return false;
+    }
+
+    // Macro for all PS types
+    #define PM_BAD_PIXELS(TYPE)                                                                              \
+case PS_TYPE_##TYPE:                                                                                         \
+    for(j=totOffRow; j<inImage->numRows; j++) {                                                              \
+        for(i=totOffCol; i<inImage->numCols; i++) {                                                          \
+            \
+            /* Pixels with flux greater than sat shall be masked */                                          \
+            if(inImage->data.TYPE[j][i] > sat) {                                                             \
+                inMask->data.PS_TYPE_MASK_DATA[j][i] |= PM_MASK_SAT;                                         \
+            }                                                                                                \
+            \
+            /* Pixels which satisfy maskVal shall be masked */                                               \
+            inMask->data.PS_TYPE_MASK_DATA[j][i] |= (mask->data.PS_TYPE_MASK_DATA[j][i]&maskVal);            \
+            \
+            /* Pixels which satisfy growVal and within the grow radius shall be masked */                    \
+            if(mask->data.PS_TYPE_MASK_DATA[j][i] & growVal) {                                               \
+                rowMin = MAX(j-grow, 0);                                                                     \
+                rowMax = MIN(j+grow+1, inImage->numRows);                                                    \
+                colMin = MAX(i-grow, 0);                                                                     \
+                colMax = MIN(i+grow+1, inImage->numCols);                                                    \
+                for(jj=rowMin; jj<rowMax; jj++) {                                                            \
+                    for(ii=colMin; ii<colMax; ii++) {                                                        \
+                        r = sqrtf((ii-i)*(ii-i)+(jj-j)*(jj-j));                                              \
+                        rRound = r + 0.5;                                                                    \
+                        if(rRound <= grow) {                                                                 \
+                            inMask->data.PS_TYPE_MASK_DATA[jj][ii] |=                                        \
+                                    (mask->data.PS_TYPE_MASK_DATA[j][i]&growVal);                            \
+                        }                                                                                    \
+                    }                                                                                        \
+                }                                                                                            \
+            }                                                                                                \
+        }                                                                                                    \
+    }                                                                                                        \
+    break;
+
+    // Switch to call bad pixel masking macro defined above
+    switch(inType) {
+        PM_BAD_PIXELS(U8);
+        PM_BAD_PIXELS(U16);
+        PM_BAD_PIXELS(U32);
+        PM_BAD_PIXELS(U64);
+        PM_BAD_PIXELS(S8);
+        PM_BAD_PIXELS(S16);
+        PM_BAD_PIXELS(S32);
+        PM_BAD_PIXELS(S64);
+        PM_BAD_PIXELS(F32);
+        PM_BAD_PIXELS(F64);
+    default:
+        psErrorMsg(PS_ERRORNAME_DOMAIN "pmMaskBadPixels", PS_ERR_BAD_PARAMETER_TYPE, true,
+                   PS_ERRORTEXT_pmMaskBadPixels_TYPE_UNSUPPORTED,
+                   inType);
+    }
+
+    return false;
+}
Index: /branches/rel3/psModules/src/pmMaskBadPixels.h
===================================================================
--- /branches/rel3/psModules/src/pmMaskBadPixels.h	(revision 2163)
+++ /branches/rel3/psModules/src/pmMaskBadPixels.h	(revision 2163)
@@ -0,0 +1,60 @@
+/** @file  pmMaskBadPixels.h
+ *
+ *  @brief Given an input image, a bad pixel mask, a corresponding value in the bad pixel mask to mask, a
+ *  saturation level, and a growing radius, mask in the input image those pixels in the bad pixel mask that
+ *  match the value to mask.
+ *
+ *  Given an input image, in, a bad pixel mask, a corresponding value in the bad pixel mask to mask in the
+ *  input image, maskVal, a saturation level, and a growing radius, pmMaskBadPixels shall mask in the input
+ *  image those pixels in the bad pixel mask that match the value to mask. Note that the input image, in, is
+ *  modified in-place. All pixels in the mask which satisfy the maskVal shall have their corresponding pixels
+ *  masked in the input image, in. All pixels which satisfy the growVal shall have their corresponding
+ *  pixels, along with all pixels within the grow radius masked. Pixels which have flux greater than sat shall
+ *  also be masked, but not grown. Note that the input image, in, and the mask need not be the same size,
+ *  since the input image may already have been trimmed (following overscan subtraction), but the function
+ *  shall use the offsets in the image (in->x0 and in->y0) to determine the appropriate offsets to obtain the
+ *  correct pixel on the mask. In the event that the mask image is too small (i.e., pixels on the input image
+ *  refer to pixels outside the range of the mask image), the function shall generate an error.
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-17 00:49:04 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "pslib.h"
+
+/** Mask values */
+typedef enum {
+    PM_MASK_TRAP    = 0x0001,   ///< The pixel is a charge trap.
+    PM_MASK_BADCOL  = 0x0002,   ///< The pixel is a bad column.
+    PM_MASK_SAT     = 0x0004,   ///< The pixel is saturated.
+    PM_MASK_FLAT    = 0x0008    ///< The pixel is non-positive in the flat-field.
+} pmMaskValue;
+
+/** Macro to find maximum of two numbers */
+#define MAX(A,B)((A)>=(B)?(A):(B))
+
+/** Macro to find minimum of two numbers */
+#define MIN(A,B)((A)<=(B)?(A):(B))
+
+
+/** Execute bad pixels module.
+ *
+ *  Given an input image, a bad pixel mask, a corresponding value in the bad pixel mask to mask, a
+ *  saturation level, and a growing radius, mask in the input image those pixels in the bad pixel mask that
+ *  match the value to mask.
+ *
+ *  @return  bool: True or false for success or failure
+ */
+bool pmMaskBadPixels(
+    psReadout *in,          ///< Readout containing input image data.
+    const psImage *mask,    ///< Mask data to be added to readout mask data.
+    unsigned int maskVal,   ///< Mask value to determine what to add to input mask.
+    float sat,              ///< Saturation limit to mask bad pixels.
+    unsigned int growVal,   ///< Mask data to determine if a circurlar area should be masked.
+    int grow                ///< Radius of mask to apply around pixel.
+);
+
Index: /branches/rel3/psModules/src/pmMaskBadPixelsErrors.dat
===================================================================
--- /branches/rel3/psModules/src/pmMaskBadPixelsErrors.dat	(revision 2163)
+++ /branches/rel3/psModules/src/pmMaskBadPixelsErrors.dat	(revision 2163)
@@ -0,0 +1,20 @@
+#
+#  This file is used to generate pmMaskBadPixelsErrors.h content
+#
+#  Format is:
+#  ERRORNAME(one word)    ERRORTEXT
+#
+#  N.B. in code, the ERRORNAME appears as PS_ERRORTEXT_ERRORNAME
+####################################################################
+#
+pmMaskBadPixels_NULL_MASK_IMAGE            Null not allowed for mask image.
+pmMaskBadPixels_NULL_INPUT_IMAGE           Null not allowed for input image.
+pmMaskBadPixels_SIZE_INPUT_IMAGE           Input image size exceeds that of mask image: (%d, %d) vs (%d, %d)
+pmMaskBadPixels_SIZE_MASK_IMAGE            Input image mask size exceeds that of mask image: (%d, %d) vs (%d, %d)
+pmMaskBadPixels_OFFSET_MASK_IMAGE          Total offset >= mask image: (%d, %d) vs (%d, %d)
+pmMaskBadPixels_OFFSET_INPUT_IMAGE         Total offset >= input image: (%d, %d) vs (%d, %d)
+pmMaskBadPixels_OFFSET_INPUT_IMAGE_MASK    Total offset >= input image mask: (%d, %d) vs (%d, %d)
+pmMaskBadPixels_TYPE_INPUT_IMAGE           Complex types not allowed for input image. Type: %d
+pmMaskBadPixels_TYPE_MASK_IMAGE            Mask must be PS_TYPE_MASK type. Type: %d
+pmMaskBadPixels_TYPE_MISMATCH              Input and flat image types differ: (%d vs %d)
+pmMaskBadPixels_TYPE_UNSUPPORTED           Unsupported image datatype. Type: %d
Index: /branches/rel3/psModules/src/pmMaskBadPixelsErrors.h
===================================================================
--- /branches/rel3/psModules/src/pmMaskBadPixelsErrors.h	(revision 2163)
+++ /branches/rel3/psModules/src/pmMaskBadPixelsErrors.h	(revision 2163)
@@ -0,0 +1,45 @@
+/** @file  pmMaskBadPixelsErrors.h
+ *
+ *  @brief Contains the error text for the mask bad pixels module
+ *
+ *  @ingroup ErrorHandling
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-24 18:00:28 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#ifndef PM_FLATFIELD_ERRORS_H
+#define PM_FLATFIELD_ERRORS_H
+
+/* N.B., lines between '//~Start' and '//~End' are automatic generated from
+ * the template following the '//~Start'.  The template is used to generate
+ * the other lines by, for each error text in pmMaskBadPixelsErrors.dat, the following
+ * substitutions are made:
+ *     $1  The error text macro name (first word in the pmMaskBadPixelsErrors.h lines)
+ *     $2  The error text (rest of the line in pmMaskBadPixelsErrors.h)
+ *     $n  The order of the source line in pmMaskBadPixelsErrors.h (comments excluded)
+ * 
+ * DO NOT EDIT THE LINES BETWEEN //~Start and //~End!  ANY CHANGES WILL BE OVERWRITTEN.
+ */
+
+#define PS_ERRORNAME_DOMAIN "psModule.src."
+
+//~Start #define PS_ERRORTEXT_$1 "$2"
+#define PS_ERRORTEXT_pmMaskBadPixels_NULL_MASK_IMAGE "Null not allowed for mask image."
+#define PS_ERRORTEXT_pmMaskBadPixels_NULL_INPUT_IMAGE "Null not allowed for input image."
+#define PS_ERRORTEXT_pmMaskBadPixels_SIZE_INPUT_IMAGE "Input image size exceeds that of mask image: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmMaskBadPixels_SIZE_MASK_IMAGE "Input image mask size exceeds that of mask image: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmMaskBadPixels_OFFSET_MASK_IMAGE "Total offset >= mask image: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmMaskBadPixels_OFFSET_INPUT_IMAGE "Total offset >= input image: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmMaskBadPixels_OFFSET_INPUT_IMAGE_MASK "Total offset >= input image mask: (%d, %d) vs (%d, %d)"
+#define PS_ERRORTEXT_pmMaskBadPixels_TYPE_INPUT_IMAGE "Complex types not allowed for input image. Type: %d"
+#define PS_ERRORTEXT_pmMaskBadPixels_TYPE_MASK_IMAGE "Mask must be PS_TYPE_MASK type. Type: %d"
+#define PS_ERRORTEXT_pmMaskBadPixels_TYPE_MISMATCH "Input and flat image types differ: (%d vs %d)"
+#define PS_ERRORTEXT_pmMaskBadPixels_TYPE_UNSUPPORTED "Unsupported image datatype. Type: %d"
+//~End
+
+#endif
Index: /branches/rel3/psModules/src/pmNonLinear.c
===================================================================
--- /branches/rel3/psModules/src/pmNonLinear.c	(revision 2163)
+++ /branches/rel3/psModules/src/pmNonLinear.c	(revision 2163)
@@ -0,0 +1,111 @@
+/** @file  pmNonLinear.c
+ *
+ *  Provides polynomial or table lookup non-linearity corrections to readouts.
+ *
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 21:44:08 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include<stdio.h>
+#include<math.h>
+
+#include "pmNonLinear.h"
+
+/******************************************************************************
+pmNonLinearityLookup(): This routine will take an psReadout image as input
+and a 1-D polynomial.  For each pixel in the input image, the polynomial will
+be evaluated at that pixels value, and the image pixel will then be set to
+that value.
+ *****************************************************************************/
+
+psReadout *pmNonLinearityPolynomial(psReadout *in,
+                                    const psPolynomial1D *coeff)
+{
+    int i;
+    int j;
+
+    PS_CHECK_NULL_PTR_RETURN_NULL(in);
+    PS_CHECK_NULL_PTR_RETURN_NULL(in->image);
+    PS_CHECK_NULL_PTR_RETURN_NULL(coeff);
+
+    for (i=0;i<(in->image)->numRows;i++) {
+        for (j=0;j<(in->image)->numCols;j++) {
+            (in->image)->data.F32[i][j] = psPolynomial1DEval((in->image)->data.F32[i][j], coeff);
+        }
+    }
+    return(in);
+}
+
+
+/******************************************************************************
+pmNonLinearityLookup(): This routine will take an psReadout image as input
+and two input vectors, which constitute a lookup table.  For each pixel in
+the input image, that pixels value will be determined in the input vector
+inFluxe, and the corresponding value in outFlux.  The image pixel will then
+be set to the value from outFlux.
+ *****************************************************************************/
+psReadout *pmNonLinearityLookup(psReadout *in,
+                                const psVector *inFlux,
+                                const psVector *outFlux)
+{
+    PS_CHECK_NULL_PTR_RETURN_NULL(in);
+    PS_CHECK_NULL_PTR_RETURN_NULL(in->image);
+    PS_CHECK_NULL_PTR_RETURN_NULL(inFlux);
+    PS_CHECK_NULL_PTR_RETURN_NULL(outFlux);
+
+    int i;
+    int j;
+    int tableSize = inFlux->n;
+    int binNum;
+    psScalar x;
+    int numPixels = 0;
+    float slope;
+
+    x.type.type = PS_TYPE_F32;
+    if (inFlux->n != outFlux->n) {
+        // XXX: psWarning("pmNonLinearityLookup(): input vectors have different size");
+        tableSize = PS_MIN(inFlux->n, outFlux->n);
+    }
+    if (inFlux->n < 2) {
+        // XXX: psWarning("pmNonLinearityLookup(): input vector less than 2 elements");
+        return(in);
+    }
+    for (i=0;i<(in->image)->numRows;i++) {
+        for (j=0;j<(in->image)->numCols;j++) {
+            x.data.F32 = (in->image)->data.F32[i][j];
+
+            binNum = p_psVectorBinDisect((psVector *)inFlux, &x);
+
+            if (binNum == -2) {
+                // We get here if x is below the table lookup range.
+                (in->image)->data.F32[i][j] = outFlux->data.F32[0];
+                numPixels++;
+
+            } else if (binNum == -1) {
+                // We get here if x is above the table lookup range.
+                (in->image)->data.F32[i][j] = outFlux->data.F32[tableSize-1];
+
+                numPixels++;
+            } else {
+                // Perform linear interpolation.
+                slope = (outFlux->data.F32[binNum+1] - outFlux->data.F32[binNum]) /
+                        (inFlux->data.F32[binNum+1]  - inFlux->data.F32[binNum]);
+                (in->image)->data.F32[i][j] = outFlux->data.F32[binNum] +
+                                              ((x.data.F32 - inFlux->data.F32[binNum]) * slope);
+            }
+        }
+    }
+    if (numPixels > 0) {
+        // XXX: psWarning("Warning: pmNonLinearityLookup(): %d pixels outside table.", numPixels);
+    }
+    return(in);
+}
Index: /branches/rel3/psModules/src/pmNonLinear.h
===================================================================
--- /branches/rel3/psModules/src/pmNonLinear.h	(revision 2163)
+++ /branches/rel3/psModules/src/pmNonLinear.h	(revision 2163)
@@ -0,0 +1,26 @@
+/** @file  pmNonLinear.h
+ *
+ *  Provides polynomial or table lookup non-linearity corrections to readouts.
+ *
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 19:01:37 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#if !defined(PM_NON_LINEAR_H)
+#define PM_NON_LINEAR_H
+
+#include "pslib.h"
+
+psReadout *pmNonLinearityPolynomial(psReadout *in,
+                                    const psPolynomial1D *coeff);
+
+psReadout *pmNonLinearityLookup(psReadout *in,
+                                const psVector *inFlux,
+                                const psVector *outFlux);
+
+#endif
Index: /branches/rel3/psModules/src/pmSubtractBias.c
===================================================================
--- /branches/rel3/psModules/src/pmSubtractBias.c	(revision 2163)
+++ /branches/rel3/psModules/src/pmSubtractBias.c	(revision 2163)
@@ -0,0 +1,412 @@
+/** @file  pmSubtractBias.c
+ *
+ *  This file will contain a module which will subtract the detector bias
+ *  in place from an input image.
+ *
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-15 02:20:39 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "pmSubtractBias.h"
+
+#define PM_SUBTRACT_BIAS_POLYNOMIAL_ORDER 2
+#define PM_SUBTRACT_BIAS_SPLINE_ORDER 3
+
+/******************************************************************************
+psSubtractFrame(): this routine will take as input a readout for the input
+image and a readout for the bias image.  The bias image is subtracted in
+place from the input image.
+ *****************************************************************************/
+psReadout *psSubtractFrame(psReadout *in,
+                           const psReadout *bias)
+{
+    int i;
+    int j;
+
+    if (bias == NULL) {
+        printf("WARNING: bias frame is NULL\n");
+        return(in);
+    }
+
+    if (((in->image)->numRows + in->row0 - bias->row0) > (bias->image)->numRows) {
+        psError(__func__, "bias image does not have enough rows\n");
+    }
+    if (((in->image)->numCols + in->row0 - bias->row0) > (bias->image)->numCols) {
+        psError(__func__, "bias image does not have enough columns\n");
+    }
+
+    // XXX: Verify that this is the correct way to use offsets.
+    for (i=0;i<(in->image)->numRows;i++) {
+        for (j=0;j<(in->image)->numCols;j++) {
+            (in->image)->data.F32[i][j]-=
+                (bias->image)->data.F32[i+in->row0-bias->row0][j+in->col0-bias->col0];
+            if ((in->mask != NULL) && (bias->mask != NULL)) {
+                ((in->mask)->data.U8[i][j])|=
+                    (bias->mask)->data.U8[i+in->row0-bias->row0][j+in->col0-bias->col0];
+            }
+        }
+    }
+
+    return(in);
+}
+
+/******************************************************************************
+p_psImageSubtractScalar(): subtract a scalar from the input image.
+ 
+// XXX: Is there already a function which does this?
+ *****************************************************************************/
+psImage *p_psImageSubtractScalar(psImage *image,
+                                 float scalar)
+{
+    int i;
+    int j;
+
+    for (i=0;i<image->numRows;i++) {
+        for (j=0;j<image->numCols;j++) {
+            (image->data.F32[i][j])-= scalar;
+        }
+    }
+    return(image);
+}
+
+/******************************************************************************
+GenNewStatOptions(): this routine will take as input the options member of
+the stat data structure, determine if multiple options have been specified,
+issue a warning message if so, and return the highest priority option
+(according to the order of the if-statements in this code).
+ *****************************************************************************/
+psStatsOptions GenNewStatOptions(const psStats *stat)
+{
+    int numOptions = 0;
+    psStatsOptions opt = 0;
+
+    if (stat->options & PS_STAT_SAMPLE_MEAN) {
+        numOptions++;
+        opt = PS_STAT_SAMPLE_MEAN;
+    }
+
+    if (stat->options & PS_STAT_SAMPLE_MEDIAN) {
+        if (numOptions == 0) {
+            opt = PS_STAT_SAMPLE_MEDIAN;
+        }
+        numOptions++;
+    }
+
+    if (stat->options & PS_STAT_CLIPPED_MEAN) {
+        if (numOptions == 0) {
+            opt = PS_STAT_CLIPPED_MEAN;
+        }
+        numOptions++;
+    }
+
+    if (stat->options & PS_STAT_ROBUST_MEAN) {
+        if (numOptions == 0) {
+            opt = PS_STAT_ROBUST_MEAN;
+        }
+        numOptions++;
+    }
+
+    if (stat->options & PS_STAT_ROBUST_MEDIAN) {
+        if (numOptions == 0) {
+            opt = PS_STAT_ROBUST_MEDIAN;
+        }
+        numOptions++;
+    }
+
+    if (stat->options & PS_STAT_ROBUST_MODE) {
+        if (numOptions == 0) {
+            opt = PS_STAT_ROBUST_MODE;
+        }
+        numOptions++;
+    }
+
+    if (numOptions == 0) {
+        psError(__func__, "No statistics options have been specified\n");
+    }
+    if (numOptions != 1) {
+        printf("WARNING: Too many statistics options have been specified\n");
+    }
+    return(opt);
+}
+
+/******************************************************************************
+ScaleOverscanVector(): this routine takes as input an arbitrary vector,
+creates a new vector of length n, and fills the new vector with the
+interpolated values of the old vector.  The type of interpolation is:
+    PM_FIT_POLYNOMIAL: fit a polynomial to the entire input vector data.
+    PM_FIT_SPLINE: fit splines to the input vector data.
+XXX: Doesn't it make more sense to do polynomial interpolation on a few
+elements of the input vector, rather than fit a polynomial to the entire
+vector?
+ *****************************************************************************/
+psVector *ScaleOverscanVector(psVector *overscanVector,
+                              int n,
+                              void *fitSpec,
+                              pmFit fit)
+{
+    printf("ScaleOverscanVector(%d)\n", n);
+    if (NULL == overscanVector) {
+        return(overscanVector);
+    }
+
+    psVector *newVec = psVectorAlloc(n, PS_TYPE_F32);
+    psPolynomial1D *myPoly;
+    psSpline1D *mySpline;
+    float x;
+    int i;
+
+    if (fit == PM_FIT_POLYNOMIAL) {
+        // Fit a polynomial to the old overscan vector.
+        myPoly = (psPolynomial1D *) fitSpec;
+        myPoly = psVectorFitPolynomial1D(myPoly, NULL, overscanVector, NULL);
+
+        // For each element of the new vector, convert the x-ordinate to that
+        // of the old vector, use the fitted polynomial to determine the
+        // interpolated value at that point, and set the new vector.
+        for (i=0;i<n;i++) {
+            x = ((float) i) * ((float) overscanVector->n) / ((float) n);
+            newVec->data.F32[i] = psPolynomial1DEval(x, myPoly);
+        }
+    } else if (fit == PM_FIT_SPLINE) {
+        // Fit a spline to the old overscan vector.
+        mySpline = (psSpline1D *) fitSpec;
+        mySpline = psVectorFitSpline1D(mySpline, NULL, overscanVector, NULL);
+
+        // For each element of the new vector, convert the x-ordinate to that
+        // of the old vector, use the fitted polynomial to determine the
+        // interpolated value at that point, and set the new vector.
+        for (i=0;i<n;i++) {
+            x = ((float) i) * ((float) overscanVector->n) / ((float) n);
+            newVec->data.F32[i] = psSpline1DEval(mySpline, x);
+        }
+    } else {
+        psError(__func__, "unknown fit type\n");
+    }
+
+    return(newVec);
+}
+
+psReadout *pmSubtractBias(psReadout *in,
+                          void *fitSpec,
+                          const psList *overscans,
+                          pmOverscanAxis overScanAxis,
+                          psStats *stat,
+                          int nBinOrig,
+                          pmFit fit,
+                          const psReadout *bias)
+{
+    int i;
+    int j;
+    int numBins = 0;
+    static psVector *overscanVector = NULL;
+    psVector *tmpRow = NULL;
+    psVector *tmpCol = NULL;
+    psVector *myBin = NULL;
+    psVector *binVec = NULL;
+    psListElem *tmpOverscan = NULL;
+    double statValue;
+    psImage *myOverscanImage = NULL;
+    psPolynomial1D *myPoly;
+    psSpline1D *mySpline;
+    int nBin;
+
+    PS_CHECK_NULL_PTR_RETURN_NULL(in);
+
+    //
+    //  Determine if multiple options are specified in stat.
+    //
+    if (stat != NULL) {
+        stat->options = GenNewStatOptions(stat);
+    }
+
+    if ((overscans == NULL) && (overScanAxis != PM_OVERSCAN_NONE)) {
+        psError(__func__, "(overscans == NULL) && (overScanAxis != PM_OVERSCAN_NONE)\n");
+        return(in);
+    }
+
+    if (((overScanAxis == PM_OVERSCAN_NONE) ||
+            (overScanAxis == PM_OVERSCAN_ALL)) &&
+            (fit == PM_FIT_NONE)) {
+        printf("WARNING: overScanAxis equals NONE or ALL, and fit equals NONE\n");
+        //XXX: Then what?
+    }
+
+    if (overScanAxis == PM_OVERSCAN_NONE) {
+        if (overscans != NULL) {
+            printf("WARNING: overScanAxis equals NONE and overscans does not equal NULL\n");
+        }
+        return(psSubtractFrame(in, bias));
+    }
+
+    //
+    // We subtract each overscan region from the image data.
+    //
+    if (overScanAxis == PM_OVERSCAN_ALL) {
+        tmpOverscan = (psListElem *) overscans->head;
+        while (NULL != tmpOverscan) {
+            myOverscanImage = (psImage *) tmpOverscan->data;
+            psImageStats(stat, myOverscanImage, NULL, 0xffffffff);
+            p_psGetStatValue(stat, &statValue);
+            p_psImageSubtractScalar(in->image, statValue);
+
+            tmpOverscan = tmpOverscan->next;
+        }
+        return(in);
+    }
+
+
+    tmpOverscan = (psListElem *) overscans->head;
+    while (NULL != tmpOverscan) {
+        myOverscanImage = (psImage *) tmpOverscan->data;
+
+        // XXX: Is there a better way to extract a psVector from a psImage without
+        // having to copy every element in that vector?
+        // XXX: If we get here, do we know that overScanAxis == PM_OVERSCAN_ROWS
+        // or PM_OVERSCAN_COL?
+
+        if ((overScanAxis == PM_OVERSCAN_ROWS) || (overScanAxis == PM_OVERSCAN_COLUMNS)) {
+            if (overScanAxis == PM_OVERSCAN_ROWS) {
+                // We create a row vector and subtract this vector from image.
+                overscanVector = psVectorAlloc(myOverscanImage->numCols, PS_TYPE_F32);
+                for (i=0;i<overscanVector->n;i++) {
+                    overscanVector->data.F32[i] = 0.0;
+                }
+                tmpRow = psVectorAlloc((in->image)->numRows, PS_TYPE_F32);
+
+                for (i=0;i<myOverscanImage->numCols;i++) {
+                    for (j=0;j<myOverscanImage->numRows;j++) {
+                        tmpRow->data.F32[j] = myOverscanImage->data.F32[j][i];
+                    }
+                    stat = psVectorStats(stat, tmpRow, NULL, 0);
+                    p_psGetStatValue(stat, &statValue);
+                    overscanVector->data.F32[i] = statValue;
+                }
+                psFree(tmpRow);
+                if ((fit == PM_FIT_POLYNOMIAL) || (fit == PM_FIT_SPLINE)) {
+                    psVector *newVec = ScaleOverscanVector(overscanVector, (in->image)->numCols, fitSpec, fit);
+                    psFree(overscanVector);
+                    overscanVector = newVec;
+                }
+            }
+
+            if (overScanAxis == PM_OVERSCAN_COLUMNS) {
+                // We create a column vector and subtract this vector from image.
+                overscanVector = psVectorAlloc(myOverscanImage->numRows, PS_TYPE_F32);
+                for (i=0;i<overscanVector->n;i++) {
+                    overscanVector->data.F32[i] = 0.0;
+                }
+                tmpCol = psVectorAlloc((in->image)->numCols, PS_TYPE_F32);
+
+                for (i=0;i<myOverscanImage->numRows;i++) {
+                    for (j=0;j<myOverscanImage->numCols;j++) {
+                        tmpCol->data.F32[j] = myOverscanImage->data.F32[i][j];
+                    }
+                    stat = psVectorStats(stat, tmpCol, NULL, 0);
+                    p_psGetStatValue(stat, &statValue);
+                    overscanVector->data.F32[i] = statValue;
+                }
+
+                psFree(tmpCol);
+                if ((fit == PM_FIT_POLYNOMIAL) || (fit == PM_FIT_SPLINE)) {
+                    psVector *newVec = ScaleOverscanVector(overscanVector, (in->image)->numRows, fitSpec, fit);
+                    psFree(overscanVector);
+                    overscanVector = newVec;
+                }
+            }
+
+            //
+            // Re-bin the overscan vector (change its length).
+            //
+            if ((nBinOrig > 0) && (nBinOrig < overscanVector->n)) {
+                numBins = 1+((overscanVector->n)/nBinOrig);
+                myBin = psVectorAlloc(numBins, PS_TYPE_F32);
+                binVec = psVectorAlloc(nBinOrig, PS_TYPE_F32);
+
+                for (i=0;i<numBins;i++) {
+                    for(j=0;j<nBinOrig;j++) {
+                        if (overscanVector->n > ((i*nBinOrig)+j)) {
+                            binVec->data.F32[j] = overscanVector->data.F32[(i*nBinOrig)+j];
+                        } else {
+                            // XXX: we get here if nBinOrig does not evenly divide
+                            // the overscanVector vector.  This is the last bin.  Should
+                            // we change the binVec->n to acknowledge that?
+                            binVec->n = j;
+                        }
+                    }
+                    stat = psVectorStats(stat, binVec, NULL, 0);
+                    p_psGetStatValue(stat, &statValue);
+                    myBin->data.F32[i] = statValue;
+                }
+
+                // Change the effective size of overscanVector.
+                overscanVector->n = numBins;
+                for (i=0;i<numBins;i++) {
+                    overscanVector->data.F32[i] = myBin->data.F32[i];
+                }
+                psFree(binVec);
+                psFree(myBin);
+                nBin = nBinOrig;
+            } else {
+                nBin = 1;
+            }
+
+            //
+            // Fit a polynomial to the overscan vector.
+            //
+            if (!((fitSpec == NULL) || (fit == PM_FIT_NONE))) {
+                if (fit == PM_FIT_POLYNOMIAL) {
+                    myPoly = (psPolynomial1D *) fitSpec;
+                    myPoly = psVectorFitPolynomial1D(myPoly, NULL, overscanVector, NULL);
+                    for (i=0;i<numBins;i++) {
+                        overscanVector->data.F32[i] = psPolynomial1DEval((float) i, myPoly);
+                    }
+
+                } else if (fit == PM_FIT_SPLINE) {
+                    mySpline = (psSpline1D *) fitSpec;
+                    // XXX: The spline functions do not currently work if the number of
+                    // data points and the number of splines are not equal.
+                }
+            }
+
+            //
+            // Subtract overscan vector row-wise from the image.
+            //
+            if (overScanAxis == PM_OVERSCAN_ROWS) {
+                for (i=0;i<(in->image)->numCols;i++) {
+                    for (j=0;j<(in->image)->numRows;j++) {
+                        (in->image)->data.F32[j][i]-= overscanVector->data.F32[i/nBin];
+                    }
+                }
+            }
+
+            //
+            // Subtract overscan vector column-wise from the image.
+            //
+            if (overScanAxis == PM_OVERSCAN_COLUMNS) {
+                for (i=0;i<(in->image)->numRows;i++) {
+                    for (j=0;j<(in->image)->numCols;j++) {
+                        (in->image)->data.F32[i][j]-= overscanVector->data.F32[i/nBin];
+                    }
+                }
+            }
+            psFree(overscanVector);
+        }
+        tmpOverscan = tmpOverscan->next;
+    }
+
+
+    if (bias != NULL) {
+        return(psSubtractFrame(in, bias));
+    }
+    return(in);
+}
+
+
Index: /branches/rel3/psModules/src/pmSubtractBias.h
===================================================================
--- /branches/rel3/psModules/src/pmSubtractBias.h	(revision 2163)
+++ /branches/rel3/psModules/src/pmSubtractBias.h	(revision 2163)
@@ -0,0 +1,50 @@
+/** @file  pmSubtractBias.h
+ *
+ *  This file will contain a module which will subtract the detector bias
+ *  in place from an input image.
+ *
+ *  @author George Gusciora, MHPCC
+ *
+ *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 18:30:08 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ *
+ */
+
+#if !defined(PM_SUBTRACT_BIAS_H)
+#define PM_SUBTRACT_BIAS_H
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include<stdio.h>
+#include<math.h>
+#include "pslib.h"
+// XXX: have Desonia do this correctly.
+#include "../../psLib/src/dataManip/psConstants.h"
+
+typedef enum {
+    PM_OVERSCAN_NONE,                         ///< No overscan subtraction
+    PM_OVERSCAN_ROWS,                         ///< Subtract rows
+    PM_OVERSCAN_COLUMNS,                      ///< Subtract columns
+    PM_OVERSCAN_ALL                           ///< Subtract the statistic of all pixels in overscan region
+} pmOverscanAxis;
+
+typedef enum {
+    PM_FIT_NONE,                              ///< No fit
+    PM_FIT_POLYNOMIAL,                        ///< Fit polynomial
+    PM_FIT_SPLINE                             ///< Fit cubic splines
+} pmFit;
+
+psReadout *pmSubtractBias(psReadout *in,
+                          void *fitSpec,
+                          const psList *overscans,
+                          pmOverscanAxis overScanAxis,
+                          psStats *stat,
+                          int nBin,
+                          pmFit fit,
+                          const psReadout *bias);
+
+#endif
Index: /branches/rel3/psModules/src/psErrorCodes.dat
===================================================================
--- /branches/rel3/psModules/src/psErrorCodes.dat	(revision 2163)
+++ /branches/rel3/psModules/src/psErrorCodes.dat	(revision 2163)
@@ -0,0 +1,18 @@
+#
+#  This file is used to generate psErrorCode.h content
+#
+# Format:
+#    ERROR_CLASS_NAME    ERROR_CLASS_DESCRIPTION
+#
+# Note: the ERROR_CLASS_NAME will appear in the code with a "PS_ERR_" prefix
+#
+UNKNOWN                        unknown error
+IO                             I/O error
+LOCATION_INVALID               specified location is unknown
+MEMORY_CORRUPTION              memory corruption detected
+MEMORY_DEREF_USAGE             dereferenced memory still used
+BAD_PARAMETER_VALUE            parameter is out-of-range
+BAD_PARAMETER_TYPE             parameter is of unsupported type
+BAD_PARAMETER_NULL             parameter is null
+BAD_PARAMETER_SIZE             size of parameter's data is outside of acceptable range.
+UNEXPECTED_NULL                unexpected NULL found
Index: /branches/rel3/psModules/src/psTest.c
===================================================================
--- /branches/rel3/psModules/src/psTest.c	(revision 2163)
+++ /branches/rel3/psModules/src/psTest.c	(revision 2163)
@@ -0,0 +1,244 @@
+//
+// C Implementation: psTest
+//
+// Description:
+//
+//
+// Author: Robert DeSonia <robert.desonia@mhpcc.hpc.mil>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "psTest.h"
+#include "psMemory.h"
+#include "psError.h"
+#include "psTrace.h"
+
+#define HEADER_TOP    "/***************************** TESTPOINT ******************************************\\\n"
+#define HEADER_LINE_STRING   "* %20s: %-58s *\n"
+#define HEADER_LINE_INT      "* %20s: %-58d *\n"
+#define HEADER_BOTTOM "\\**********************************************************************************/\n\n"
+
+bool p_runTestSuite( FILE *fp, const char* testPointFile, const char* packageName,
+                     testDescription tests[], int argc, char * const argv[] )
+{
+    bool success = true;
+    bool runAll = true;
+    bool useFork = true;
+    bool found;
+    int c;
+    int n;
+    extern char *optarg;
+
+    if ( argc > 0 ) {
+        while ( ( c = getopt( argc, argv, "lhn:dt:" ) ) != -1 ) {
+            switch ( c ) {
+            case 'h':
+                printf( "Usage: %s [-l] [-d] [-h] [-n=Testpoint#] [-t=TestpointName]\n"
+                        "    where:\n"
+                        "           -l  : lists the testpoints contained in this test driver executable\n"
+                        "           -d  : turns on debugger-friendly mode (no forking, aborts/signals are not handled)\n"
+                        "           -h  : prints this help\n"
+                        "           -n  : specifies a particular testpoint by number to run\n"
+                        "           -t  : specifies a particular testpoint by name to run\n"
+                        "    (if no -l, -n or -t options are given, all testpoints are run)\n",
+                        argv[ 0 ] );
+                runAll = false;
+                break;
+            case 'd':
+                useFork = false;
+                break;
+            case 'l':
+                printf( "Test Driver:  %s\n", testPointFile );
+                printf( "Package Name: %s\n", packageName );
+                printf( "Testpoints:\n" );
+                runAll = false;
+                for ( int index = 0; tests[ index ].fcn != NULL; index++ ) {
+                    printf( "    %6d - %s \n", tests[ index ].testPointNumber,
+                            tests[ index ].testPointName );
+                }
+                printf( "\n" );
+                break;
+            case 't':
+                runAll = false;
+                for ( int index = 0; tests[ index ].fcn != NULL; index++ ) {
+                    if ( strcmp( optarg, tests[ index ].testPointName ) == 0 ) {
+                        success = p_runTest( fp,
+                                             testPointFile,
+                                             packageName,
+                                             tests[ index ].testPointName,
+                                             tests[ index ].fcn,
+                                             tests[ index ].expectedReturn,
+                                             useFork ) && success;
+                    }
+                }
+                break;
+            case 'n':
+                runAll = false;
+                if ( sscanf( optarg, "%i", &n ) != 1 ) {
+                    psError( __func__, "Failed to parse the testpoint number (%s).",
+                             optarg );
+                    break;
+                }
+                found = false;
+                for ( int index = 0; tests[ index ].fcn != NULL; index++ ) {
+                    if ( n == tests[ index ].testPointNumber ) {
+                        found = true;
+                        success = p_runTest( fp,
+                                             testPointFile,
+                                             packageName,
+                                             tests[ index ].testPointName,
+                                             tests[ index ].fcn,
+                                             tests[ index ].expectedReturn,
+                                             useFork ) && success;
+                    }
+                }
+                if ( ! found ) {
+                    psError( __func__, "The specified testpoint number (%d) doesn't exist in this test driver.",
+                             n );
+                    break;
+                }
+                break;
+            case '?':
+                psError( __func__, "Option %s is not recognized and is ignored.", optarg );
+                break;
+            }
+        }
+    }
+
+    if ( runAll ) {
+        for ( int index = 0; tests[ index ].fcn != NULL; index++ ) {
+            if ( ! tests[ index ].isDuplicateEntry ) {
+                success = p_runTest( fp,
+                                     testPointFile,
+                                     packageName,
+                                     tests[ index ].testPointName,
+                                     tests[ index ].fcn,
+                                     tests[ index ].expectedReturn,
+                                     useFork ) && success;
+            }
+        }
+    }
+
+    if ( ! success ) {
+        psError( testPointFile, "One or more tests failed" );
+    }
+
+    return success;
+}
+
+bool p_runTest( FILE *fp, const char* testPointFile, const char* packageName, const char* testPointName,
+                testFcn fcn, int expectedReturn, bool useFork )
+{
+    int childReturn = 0;
+    pid_t child;
+
+    p_printPositiveTestHeader( fp, testPointFile, packageName, testPointName );
+
+    if ( useFork ) {
+        child = fork();
+        if ( child == 0 ) {                   // I am the child process, run the test
+            int currentId = psMemGetId();
+            int retVal = fcn();
+            if ( retVal == 0 ) { // only bother checking memory if test executed to end.
+                if ( psMemCheckLeaks( currentId, NULL, stderr ) != 0 ) {
+                    psError( __func__, "Memory Leaks Detected" );
+                    retVal = 64;
+                }
+                psMemCheckCorruption( 1 );
+            }
+            exit( retVal );
+        } else
+            if ( child < 0 ) {
+                fprintf( fp, "Couldn't fork a process to run a negative test (%s|%s)",
+                         packageName, testPointName );
+                abort();
+            }
+
+        waitpid( child, &childReturn, 0 );
+        if ( WIFSIGNALED( childReturn ) ) {
+            childReturn = -WTERMSIG( childReturn );
+        } else {
+            childReturn = WEXITSTATUS( childReturn );
+        }
+    } else {
+        int currentId = psMemGetId();
+        childReturn = fcn();
+        if ( childReturn == 0 ) { // only bother checking memory if test executed to end.
+            if ( psMemCheckLeaks( currentId, NULL, stderr ) != 0 ) {
+                psError( __func__, "Memory Leaks Detected" );
+                childReturn = 64;
+            }
+            psMemCheckCorruption( 1 );
+        }
+    }
+
+
+    if ( childReturn != expectedReturn ) {
+        fprintf( fp, "Return value mismatch: expected %d, got %d",
+                 expectedReturn, childReturn );
+    }
+
+    p_printFooter( fp, testPointFile, packageName, testPointName,
+                   ( childReturn == expectedReturn ) );
+
+    return ( childReturn == expectedReturn );
+}
+
+void p_printPositiveTestHeader( FILE *fp,
+                                const char* testPointFile,
+                                const char* packageName,
+                                const char* testPointName )
+{
+    char TP[ 80 ];
+
+    snprintf( TP, 80, "%s{%s}", packageName, testPointName );
+
+    fprintf( fp, HEADER_TOP );
+    fprintf( fp, HEADER_LINE_STRING, "TestFile", testPointFile );
+    fprintf( fp, HEADER_LINE_STRING, "TestPoint", TP );
+    fprintf( fp, HEADER_LINE_STRING, "TestType", "Positive" );
+    fprintf( fp, HEADER_BOTTOM );
+}
+
+void p_printNegativeTestHeader( FILE *fp,
+                                const char* testPointFile,
+                                const char* packageName,
+                                const char* testPointName,
+                                const char* expectedError,
+                                int exitValue )
+{
+    char TP[ 80 ];
+
+    snprintf( TP, 80, "%s{%s}", packageName, testPointName );
+
+    fprintf( fp, HEADER_TOP );
+    fprintf( fp, HEADER_LINE_STRING, "TestFile", testPointFile );
+    fprintf( fp, HEADER_LINE_STRING, "TestPoint", TP );
+    fprintf( fp, HEADER_LINE_STRING, "TestType", "Negative" );
+    fprintf( fp, HEADER_LINE_STRING, "ExpectedErrorText", expectedError );
+    fprintf( fp, HEADER_LINE_INT, "ExpectedStatusValue", exitValue );
+    fprintf( fp, HEADER_BOTTOM );
+}
+
+
+void p_printFooter( FILE *fp,
+                    const char* testPointFile,
+                    const char* packageName,
+                    const char* testPointName,
+                    bool success )
+{
+    if ( success ) {
+        fprintf( fp, "\n---> TESTPOINT PASSED (%s{%s} | %s)\n\n", packageName, testPointName, testPointFile );
+    } else {
+        fprintf( fp, "\n---> TESTPOINT FAILED (%s{%s} | %s)\n\n", packageName, testPointName, testPointFile );
+    }
+}
Index: /branches/rel3/psModules/src/psTest.h
===================================================================
--- /branches/rel3/psModules/src/psTest.h	(revision 2163)
+++ /branches/rel3/psModules/src/psTest.h	(revision 2163)
@@ -0,0 +1,81 @@
+
+#ifndef PSTEST_H
+#define PSTEST_H
+
+#include <stdio.h>
+#include <stdbool.h>
+
+#define printPositiveTestHeader(filePtr, packageName, testPointName) \
+p_printPositiveTestHeader(filePtr, __FILE__, packageName, testPointName)
+
+#define printNegativeTestHeader(filePtr, packageName, testPointName, expectedError, exitValue) \
+p_printNegativeTestHeader(filePtr, __FILE__, packageName, testPointName, expectedError, exitValue)
+
+#define printFooter(filePtr, packageName, testPointName, success) \
+p_printFooter(filePtr, __FILE__, packageName, testPointName, success)
+
+typedef int (*testFcn)(void);
+
+typedef struct
+{
+    testFcn     fcn;
+    int         testPointNumber;
+    const char* testPointName;
+    int         expectedReturn;
+    bool        isDuplicateEntry;
+}
+testDescription;
+
+#define runTest(filePtr, packageName, testPointName, fcn, expectedReturn, useFork) \
+p_runTest(filePtr, __FILE__, packageName, testPointName, fcn, expectedReturn, useFork)
+
+#define runTestSuite(filePtr, packageName, tests, argc, argv) \
+p_runTestSuite(filePtr, __FILE__, packageName, tests, argc, argv)
+
+
+/////////////////////////// PRIVATE FUNCTIONS //////////////////////////////
+
+bool p_runTest(
+    FILE *fp,
+    const char* testPointFile,
+    const char* packageName,
+    const char* testPointName,
+    testFcn fcn,
+    int expectedReturn,
+    bool useFork
+);
+
+bool p_runTestSuite(
+    FILE *fp,
+    const char* testPointFile,
+    const char* packageName,
+    testDescription tests[],
+    int argc,
+    char * const argv[]
+);
+
+void p_printPositiveTestHeader(
+    FILE *fp,
+    const char* testPointFile,
+    const char* packageName,
+    const char* testPointName
+);
+
+void p_printNegativeTestHeader(
+    FILE *fp,
+    const char* testPointFile,
+    const char* packageName,
+    const char* testPointName,
+    const char* expectedError,
+    int exitValue
+);
+
+void p_printFooter(
+    FILE *fp,
+    const char* testPointFile,
+    const char* packageName,
+    const char* testPointName,
+    bool success
+);
+
+#endif
Index: /branches/rel3/psModules/templates/c
===================================================================
--- /branches/rel3/psModules/templates/c	(revision 2163)
+++ /branches/rel3/psModules/templates/c	(revision 2163)
@@ -0,0 +1,11 @@
+/** @file  filename.c
+ *
+ *  @brief Contains the definitions for ...
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1.1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-10 19:01:33 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
Index: /branches/rel3/psModules/templates/h
===================================================================
--- /branches/rel3/psModules/templates/h	(revision 2163)
+++ /branches/rel3/psModules/templates/h	(revision 2163)
@@ -0,0 +1,13 @@
+/** @file  filename.h
+ *
+ *  @brief Contains the definitions for ...
+ *
+ *  Detailed Description goes here.
+ *
+ *  @author Robert DeSonia, MHPCC
+ *
+ *  @version $Revision: 1.1.1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-10 19:01:33 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
Index: /branches/rel3/psModules/test/.cvsignore
===================================================================
--- /branches/rel3/psModules/test/.cvsignore	(revision 2163)
+++ /branches/rel3/psModules/test/.cvsignore	(revision 2163)
@@ -0,0 +1,8 @@
+.deps
+.libs
+Makefile
+tst_pmFlatField
+tst_pmMaskBadPixels
+tst_pmNonLinear
+tst_pmSubtractBias
+temp
Index: /branches/rel3/psModules/test/FullUnitTest
===================================================================
--- /branches/rel3/psModules/test/FullUnitTest	(revision 2163)
+++ /branches/rel3/psModules/test/FullUnitTest	(revision 2163)
@@ -0,0 +1,710 @@
+#!/usr/bin/perl
+#
+#  This is a perl script test harness which will recursively search the
+#  directory tree looking for files named UnitTest and then execute
+#  the script
+#
+#  SYNOSIS :  FullUnitTest options arguements
+#
+#       where  options =
+#             --verbose     Display extra information to user
+#             --noverbose   Don't display extra information to user
+#             --recursiv e  Recursively run tests in directory tree
+#             --norecursive Test only the specified or current directory
+#             --silent      Don't display any information to user
+#             --nosilent    Display progress of script to user
+#
+#              arguements = directory(ies) to perform tests
+#
+#  RETURN : integer number of tests which failed
+#
+#  $Revision: 1.1 $  $Name: not supported by cvs2svn $
+#  $Date: 2004-10-14 23:58:56 $
+#
+#  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+#
+##############################################################################
+
+# Provide functions for determining the pathname of current working directory
+use Cwd;
+
+# Provides functions for handling long command line options
+use Getopt::Long;
+
+# Assign variables based on the presence of command line options to the script
+# The ! option allows for --nooption to be set to zero
+# (e.g. --noverbose --recursive causes $verbose=0 and $recursive=1)
+GetOptions(
+    "verbose!"   => \$verbose,
+    "recursive!" => \$recursive,
+    "silent!"    => \$silent,
+    "clean!"     => \$clean
+);
+
+# Check if both silent and verbose options are set and if so stop the script
+die "Can't specify both verbose and silent options." if ( $verbose && $silent );
+
+# Set up the PSLIB_ROOT environment variable if the user doesn't have
+if ( !$ENV{'PSLIB_ROOT'} ) {
+
+    # Use the directory directly above where FullUnitTest script resides
+    $PSLIB_ROOT = `cd ..;pwd`;
+
+    # Remove newline for the end of path returned
+    chomp($PSLIB_ROOT);
+
+    # Set the environment variable
+    $ENV{'PSLIB_ROOT'} = $PSLIB_ROOT;
+    print("PSLIB_ROOT not found: set to $PSLIB_ROOT.\n") if $verbose;
+}
+
+# add PSLIB_ROOT/lib to LD_LIBRARY_PATH and DYLD_LIBRARY_PATH environment
+# variables
+$ENV{'LD_LIBRARY_PATH'}   = "$ENV{'PSLIB_ROOT'}/lib:$ENV{'LD_LIBRARY_PATH'}";
+$ENV{'DYLD_LIBRARY_PATH'} = "$ENV{'PSLIB_ROOT'}/lib:$ENV{'DYLD_LIBRARY_PATH'}";
+
+# Initialize variables for counting the makes and test failures and the
+# total makes and tests performed
+$makeFailCount       = 0;
+$testpointFailCount  = 0;
+$testDriverFailCount = 0;
+$totalTestpoints     = 0;
+$totalTestDrivers    = 0;
+$totalMakes          = 0;
+
+# Initialize variable indicating how many arguements were passed
+$args = 0;
+
+# Loop through all the arguements passed to the script
+foreach (@ARGV) {
+
+    # Remove newline if there is one
+    chomp;
+
+    # Increment number of arguements found
+    $args++;
+
+    # Set variable to current working directory
+    $cwd = cwd;
+
+    # Change directory to the directory of the arguement
+    chdir($_);
+
+    # Check for the recursive option
+    if ($recursive) {
+
+        # Invoke subroutine to go to the lowest directory in tree
+        # starting at the specified directory
+        &worm($_);
+    }
+    else {
+
+        # Invoke subroutines to run the test at the specified directory
+        &makeTestDrivers($_);
+        &executeTestDrivers($_);
+    }
+
+    # Change directory back to the directory where FullUnitTest was invoked
+    chdir($cwd);
+}
+
+# Check if there were no arguements specified
+if ( $args == 0 ) {
+
+    # Display message to user that all directories under the current will be
+    # tested
+    print("Recursively testing current directory tree.\n") if $verbose;
+
+    # Invoke subroutine to go to recursively test each directory in tree
+    &worm( $ENV{"PWD"} );
+}
+
+# Check if there were any failures during make or testing
+if ( $makeFailCount > 0 || $testDriverFailCount > 0 ) {
+
+    # Display summary of failures
+    print("\nMake Failures = $makeFailCount out of $totalMakes");
+    print(
+"\nTest Driver Failures = $testDriverFailCount out of $totalTestDrivers\n"
+    );
+    print( "\nMakes that failed:\n  " . join( "\n  ", @makesFailed ) . "\n" )
+      if $makeFailCount;
+    print( "\nTests that failed:\n  " . join( "\n  ", @testsFailed ) . "\n" )
+      if $testDriverFailCount;
+}
+else {
+
+    # Display message of all makes and tests pass to user if silent option
+    # not specified
+    print(
+"\nAll $totalTestDrivers Test Drivers Passed with $totalTestpoints Testpoints.\n"
+      )
+      if ( !$silent );
+}
+
+# Exit with the number of tests that failed
+exit($testDriverFailCount);
+
+################################################################################
+#
+# SUBROUTINE: worm
+#
+#     Description:  This subroutine will perform the necessary unit tests be
+#                   calling makeTestDrivers and executeTestDrivers  subroutines
+#                   and then check each subdirectory below the base directory
+#                   recursively.
+#
+#     Parameter(s):  base directory to start testing
+#
+#     Return:  None
+#
+################################################################################
+
+sub worm {
+
+    # Assign local variable to input parameter
+    local ($base_dir) = @_;
+    local ( @files, $i );
+
+    # Invoke subroutine to make test driver in the base directory
+    &makeTestDrivers($base_dir);
+
+    # Invoke subroutine to execute tests in the base directory
+    &executeTestDrivers($base_dir);
+
+    # Create array of entries found in directory
+    @files = <*>;
+
+    # Loop through the file list looking for another directory that is not
+    # labelled CVS and recursively invoke subroutine worm
+    $i = 0;
+    while ( $files[$i] ) {
+
+        # Check for directory and directory not labelled CVS
+        if (   -d $files[$i]
+            && ( $files[$i] ne "CVS" )
+            && ( $files[$i] ne "temp" )
+            && ( $files[$i] ne "verified" ) )
+        {
+
+            # Change current directory to directory found
+            chdir( $files[$i] );
+
+            # Invoke subroutine worm again
+            &worm( $files[$i] );
+
+            # Change current directory back to parent
+            chdir("..");
+        }
+
+        # Increment file list index
+        $i++;
+    }
+}
+
+################################################################################
+#
+#  SUBROUTINE: makeTestDrivers
+#
+#      Description:  This subroutine will perform a make for all the necessary
+#                    test drivers.    This will occur in the specified
+#                    base directory which is passed as the only parameter.
+#
+#      Parameter(s):  base directory where make and test drivers are located
+#
+#      Return:  None
+#
+################################################################################
+
+sub makeTestDrivers {
+    local ($base_dir) = @_;
+    local ($pwd);
+
+    # Set variable pwd to current working directory
+    $pwd = cwd;
+
+    # Display message to user in which directory testing is taken place only
+    # if the silent command option was not specified
+    print("---- Entering $pwd ----\n") if ( !$silent );
+
+    # Check for the existence of a file name Makefile in current directory
+    if ( -e "Makefile" ) {
+
+        # Increment the total number of makes executed
+        $totalMakes++;
+
+        if ($clean) {
+
+            # Execute the make clean
+            `make clean`;
+
+            # Execute the make distclean
+            `make distclean`;
+        }
+
+        # Execute the make and save results
+        $_ = join( "\n|| ", split( "\n", "\n" . `make` ) );
+
+        # Check the output of make for return value != 0 or any of the
+        # following words: FAILED, FAULT, ERROR, Not found, SIGNAL
+        if (   ( $? != 0 )
+            || m/FAILED/i
+            || m/FAULT/i
+            || m/\bERROR/i
+            || m/Not found/i
+            || m/SIGNAL/i )
+        {
+
+            # Display the errored output of make if silent option not enabled
+            print("$_\n") if ( !$silent );
+
+            # Display the make failed in the current directory
+            print("\nMake for $pwd Failed\n");
+
+            # Increment the number of makes that have failed
+            $makeFailCount++;
+
+            # Push the current working directory onto the list of failed
+            # make directories list
+            push( @makesFailed, $pwd );
+        }
+        else {
+
+            # Display the results of the successful make if verbose option set
+            print("$_\n") if $verbose;
+
+            # Display the make was successful if silent option not set
+            print("\nMake successful.\n") if ( !$silent );
+            if ($clean) {
+                `make install`;
+            }
+        }
+    }
+}
+
+################################################################################
+#
+#  SUBROUTINE: executeTestDrivers
+#
+#      Description:  This subroutine will execute all the necessary
+#                    test drivers.    This will occur in the specified
+#                    base directory which is passed as the only parameter.
+#
+#      Parameter(s):  base directory where make and test drivers are located
+#
+################################################################################
+
+sub executeTestDrivers {
+    local ($base_dir) = @_;
+    local ( @files, $j );
+    local ($pwd);
+    local ($exitValue) = 0;
+
+    # Set variable to pwd to current test directory
+    $pwd = cwd;
+
+    # Create a list of all elements in base directory
+    @files = <*>;
+
+    # Loop through all the items in the files array
+    $initialTest = 0;
+    $j           = 0;
+    while ( $files[$j] ) {
+
+        # Check that the item is not a directory and is executable and
+        # conforms to the test driver naming convention TST
+        if (   !( -d $files[$j] )
+            && ( -x $files[$j] )
+            && ( $files[$j] =~ /^TST/i || $files[$j] =~ /^ATST/i ) )
+        {
+
+            # Increment total number of test drivers executed
+            $totalTestDrivers++;
+
+            # Perform subdirectory checks only the first time a test
+            # file is found with the list of enteries
+            if ( $initialTest == 0 ) {
+                $initialTest++;
+
+                # Check for a temp subdirectory already exists and if not
+                # then create one
+                &checkForTempDirectory();
+
+                # Check for the presence of verified directory
+                if ( &checkForVerifiedDirectory() ) {
+
+    # Display message to user that verified directories do not
+    # exist eventhough TST files have been found
+    #                    print("Unable to execute test drivers in $base_dir\n");
+                    print("No verified subdirectory present.\n") if ($verbose);
+
+               # Increment test fail count
+               #                   $testDriverFailCount++;
+               # Save the file failed
+               #                    push(@testsFailed, $pwd . "/" . $files[$j]);
+               #                    return;
+                }
+            }
+
+            # Display message to user of which test driver is being executed
+            print("--- Executing test driver $files[$j]\n") if ( !$silent );
+
+            # Execute the test driver
+            system(
+"./$files[$j] 1> temp/$files[$j].stdout 2> temp/$files[$j].stderr"
+            );
+            $retVal = $?;
+
+            # Count testpoints
+            $testPattern = "\"\\*\\*\\*\\* TESTPOINT \\*\\*\\*\\*\"";
+            $totalPoints = `grep -c $testPattern temp/$files[$j].stdout`;
+            $totalPoints += `grep -c $testPattern temp/$files[$j].stderr`;
+            $failPoints =
+              `grep "> TESTPOINT FAILED" temp/$files[$j].stdout | wc -l`;
+            $failPoints +=
+              `grep "> TESTPOINT FAILED" temp/$files[$j].stderr | wc -l`;
+            $testpointFailCount += $failPoints;
+            $totalTestpoints    += $totalPoints;
+
+            # Check result of test driver
+            if (   ( ( $retVal != 0 ) && ( $files[$j] =~ /^TST/i ) )
+                || ( ( $retVal == 0 ) && ( $files[$j] =~ /^ATST/i ) ) )
+            {
+
+                # Display test driver failed
+                $failPoints++;
+                print(
+                    "Test driver: $files[$j] Failed (Return value $retVal).\n");
+
+                # Increment the total number of test failed
+                $testDriverFailCount++;
+
+                # Push the current working directory on the list of failed
+                push( @testsFailed, $pwd . "/" . $files[$j] );
+            }
+            else {
+
+               # Create filter versions of STDOUT and STDERR to replace variable
+               # items such as date, time and host
+                &filterStdFiles( $files[$j] );
+
+                # Perform difference on STDOUT file collected
+                # with verified files
+                $exitValue = &compareStream("verified/$files[$j].stdout");
+                if ( $exitValue & 2 ) {
+
+                    # STDOUT verified doesn't exist. Search STDOUT capture
+                    # for strings indicating error or failure
+                    $exitValue |= &errorStrSearch("$files[$j].stdout");
+                }
+                if ( ( $exitValue & 8 ) || ( $exitValue & 64 ) ) {
+
+                    # Increment the total number of test failed
+                    $testDriverFailCount++;
+
+                    # Push test on failed list
+                    print(
+"Test failed ($failPoints out of $totalPoints testpoints failed)\n"
+                      )
+                      if ( !$silent );
+                    push( @testsFailed, $pwd . "/" . $files[$j] );
+                }
+                else {
+
+                    # Perform difference on STDERR file collection with verified
+                    $exitValue = &compareStream("verified/$files[$j].stderr");
+                    if ( $exitValue & 4 ) {
+
+                        # STDERR verified doesn't exist. Search STDERR capture
+                        # for strings indicating error or failure
+                        $exitValue |= &errorStrSearch("$files[$j].stderr");
+                    }
+                    if ( ( $exitValue & 16 ) || ( $exitValue & 128 ) ) {
+
+                        # Increment the total number of tests failed
+                        $testDriverFailCount++;
+
+                        # Push test on failed list
+                        print(
+"Test failed ($failPoints out of $totalPoints testpoints failed)\n"
+                          )
+                          if ( !$silent );
+                        push( @testsFailed, $pwd . "/" . $files[$j] );
+                    }
+                    else {
+                        print("Test successful ($totalPoints testpoints)\n")
+                          if ( !$silent );
+                    }
+                }
+            }
+        }
+        $j++;
+    }
+}
+
+################################################################################
+#
+#  SUBROUTINE: errorStrSearch
+#
+#      Description:  This subroutine will search the file specified in its
+#                    parameter for error strings and if they do exists
+#                    the appropriate value will be returned.
+#
+#      Parameter(s): fileName - input file to search for strings
+#
+#      Return:   0  -  No error strings found
+#               64  -  Error strings found in STDOUT
+#              128  -  Error strings found in STDERR
+#
+###############################################################################
+
+sub errorStrSearch {
+    local ($fileName)  = @_;
+    local ($returnVal) = 0;
+
+    # Open the captured file
+    open( CAPT_FILE, "<temp/$fileName" );
+
+    # Scan through all the lines of the file searching for error strings
+    while (<CAPT_FILE>) {
+        if (   m/FAIL/i
+            || m/FAULT/i
+            || m/ERROR/i
+            || m/Not Found/i
+            || m/SIGNAL/i
+            || m/NO SUCH FILE/i
+            || m/\|E\|/i
+            || m/\|A\|/i )
+        {
+            print;
+            if ( $fileName =~ m/out/ ) {
+                print(
+                    "        Failed - File $fileName contains error strings.\n"
+                );
+                $returnVal = 64;
+            }
+            elsif ( $fileName =~ m/err/ ) {
+                print(
+                    "        Failed - File $fileName contains error strings.\n"
+                );
+                $returnVal = 128;
+            }
+            last;
+        }
+    }
+
+    # Close the capture file
+    close(CAPT_FILE);
+
+    # Return the return value
+    return ($returnVal);
+}
+
+################################################################################
+#
+#  SUBROUTINE: compareStream
+#
+#      Description:  This subroutine will compare the captured stream file with
+#                    a file in the verified directory if one exists.
+#
+#      Parameter(s): streamFile - input file to compare
+#
+#      Return:   0  -  Compare successful
+#                2  -  STDOUT verified file doesn't exist
+#                4  -  STDERR verified file doesn't exist
+#                8  -  STDOUT verified file doesn't compare
+#               16  -  STDERR verified file doesn't compare
+#
+###############################################################################
+
+sub compareStream {
+    local ($streamFile) = @_;
+    local ($returnVal)  = 0;
+    local ($tempFile)   = "";
+
+    # Check for existence of verified STD stream files
+    if ( !( -e $streamFile ) ) {
+
+        # Display message to user that verified STDOUT file doesn't exist
+        print("        File $streamFile doesn't exist.\n") if ($verbose);
+
+        # Set exit value bit 1 to indicate proper failure
+        if ( $streamFile =~ /out$/ ) {
+            $returnVal |= 2;
+        }
+        elsif ( $streamFile =~ /err$/ ) {
+            $returnVal |= 4;
+        }
+    }
+    else {
+
+        # Verified STD stream file exists
+
+        # Create name of the temp file to compare
+        $tempFile = $streamFile;
+        $tempFile =~ s/verified/temp/;
+        $tempFile = $tempFile . ".mod";
+
+        # Perform difference on the STD stream files
+        $diffstdout = `diff $streamFile $tempFile`;
+
+        # Check the return value of the difference
+        if ( $? != 0 ) {
+
+            # Difference of STD stream files failed
+
+            # Check for STDOUT in file name to convey appropirate return value
+            if ( $streamFile =~ /out$/ ) {
+
+                # Display message of the failure of difference to user
+                print("        Failed - STDOUT difference\n$diffstdout\n");
+
+                # Exit value to indicate STDOUT did not compare
+                $returnVal |= 8;
+            }
+            elsif ( $streamFile =~ /err$/ ) {
+
+                # Display message of the failure of difference to user
+                print("        Failed - STDERR difference\n$diffstdout\n");
+
+                # Exit value to indicate STDERR did not compare
+                $returnVal |= 16;
+            }
+        }
+    }
+
+    # Return the result of the compare
+    return ($returnVal);
+}
+
+################################################################################
+#
+#  SUBROUTINE: checkForTempDirectory
+#
+#      Description:  This subroutine will check for the existence of a temp
+#                    directory to store STDOUT, STDERR files during test.  If
+#                    the subdirectory doesn't exist, it will be created.
+#
+#      Parameter(s):  None
+#
+#      Return: None
+#
+################################################################################
+
+sub checkForTempDirectory {
+
+    # Check if a temp directory already exists in the current work directory
+    if ( !( -e "temp" ) ) {
+
+        # Create temp directory to store STDOUT, STDERR files during test
+        `mkdir temp`;
+
+        # Display message of new directory created
+        print("Creating temp directory\n") if ($verbose);
+    }
+}
+
+################################################################################
+#
+#  SUBROUTINE: checkForVerifiedDirectory
+#
+#      Description:  This subroutine will check for the existence of a verified
+#                    directory which stores verified STDOUT, STDERR files for
+#                    comparison during the test.
+#
+#      Parameter(s):  None
+#
+#      Return: 0 - subdirectory present
+#              1 - subdirectory not present
+#
+################################################################################
+
+sub checkForVerifiedDirectory {
+    $returnValue = 0;
+
+    # Check if verified subdirectory exists in the current working directory
+    if ( !( -e "verified" ) ) {
+
+        # Set return value to 1
+        $returnValue = 1;
+    }
+    return ($returnValue);
+}
+
+################################################################################
+#
+#  SUBROUTINE: filterStdFiles
+#
+#      Description:  This subroutine will filter variable items in the STDOUT
+#                    and STDERR files captured.  Date, time and host names
+#                    are variable items in the log messages captured.
+#
+#      Parameter(s):  test file name
+#
+#      Return: None
+#
+################################################################################
+
+sub filterStdFiles {
+
+    local ($fileName) = @_;
+
+    # Open the STDOUT file for reading
+    open( OUTFILE, "< temp/$fileName.stdout" );
+
+    # Open mod file to place filtered STDOUT
+    open( MODFILE, "> temp/$fileName.stdout.mod" );
+
+    # Replace the variable data, time and host information with constants
+    $hostname = `hostname`;
+    chop $hostname;
+    while (<OUTFILE>) {
+        s/\s+\d+:\d+:\d+\w/<TIME>/g;
+        s/\d+:\d+:\d+/<DATE>/g;
+        s/$hostname\s*/<HOST>/g;
+        s/: Line \d+/: Line <LINENO>/g;
+        s/\:\d+/\:<LINENO>/g;
+        s/allocate \d+ bytes at/allocate <N> bytes at/g;
+
+        # Filter lines with *** malloc.  This is an artifact of Mac testing of
+        # memory functions
+        if ( !m/\*\*\*\smalloc/ ) {
+            print MODFILE ($_);
+        }
+    }
+
+    # Close mod file
+    close(MODFILE);
+
+    # Close STDERR file
+    close(OUTFILE);
+
+    # Open the STDERR file for reading
+    open( OUTFILE, "< temp/$fileName.stderr" );
+
+    # Open mod file to place filtered STDERR
+    open( MODFILE, "> temp/$fileName.stderr.mod" );
+
+    # Replace the variable date, time and host information with constants
+    while (<OUTFILE>) {
+        s/\s+\d+:\d+:\d+\w/<TIME>/g;
+        s/\d+:\d+:\d+/<DATE>/g;
+        s/$hostname\s*/<HOST>/g;
+        s/: Line \d+/: Line <LINENO>/g;
+        s/\:\d+/\:<LINENO>/g;
+        s/allocate \d+ bytes at/allocate <N> bytes at/g;
+
+        # Filter lines with *** malloc.  This is an artifact of Mac testing of
+        # memory functions
+        if ( !m/\*\*\*\smalloc/ ) {
+            print MODFILE ($_);
+        }
+    }
+
+    # Close mod file
+    close(MODFILE);
+
+    # Close STDERR file
+    close(OUTFILE);
+}
+
Index: /branches/rel3/psModules/test/Makefile.am
===================================================================
--- /branches/rel3/psModules/test/Makefile.am	(revision 2163)
+++ /branches/rel3/psModules/test/Makefile.am	(revision 2163)
@@ -0,0 +1,14 @@
+bin_PROGRAMS = tst_pmFlatField tst_pmMaskBadPixels tst_pmNonLinear tst_pmSubtractBias
+
+tst_pmFlatField_SOURCES = tst_pmFlatField.c
+tst_pmFlatField_LDFLAGS = -L../src -lpsmodule
+
+tst_pmMaskBadPixels_SOURCES = tst_pmMaskBadPixels.c
+tst_pmMaskBadPixels_LDFLAGS = -L../src -lpsmodule
+
+tst_pmNonLinear_SOURCES = tst_pmNonLinear.c
+tst_pmNonLinear_LDFLAGS = -L../src -lpsmodule
+
+tst_pmSubtractBias_SOURCES = tst_pmSubtractBias.c
+tst_pmSubtractBias_LDFLAGS = -L../src -lpsmodule
+
Index: /branches/rel3/psModules/test/Makefile.in
===================================================================
--- /branches/rel3/psModules/test/Makefile.in	(revision 2163)
+++ /branches/rel3/psModules/test/Makefile.in	(revision 2163)
@@ -0,0 +1,479 @@
+# Makefile.in generated by automake 1.8.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+SOURCES = $(tst_pmFlatField_SOURCES) $(tst_pmMaskBadPixels_SOURCES) $(tst_pmNonLinear_SOURCES) $(tst_pmSubtractBias_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+bin_PROGRAMS = tst_pmFlatField$(EXEEXT) tst_pmMaskBadPixels$(EXEEXT) \
+	tst_pmNonLinear$(EXEEXT) tst_pmSubtractBias$(EXEEXT)
+subdir = test
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/src/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_tst_pmFlatField_OBJECTS = tst_pmFlatField.$(OBJEXT)
+tst_pmFlatField_OBJECTS = $(am_tst_pmFlatField_OBJECTS)
+tst_pmFlatField_LDADD = $(LDADD)
+am_tst_pmMaskBadPixels_OBJECTS = tst_pmMaskBadPixels.$(OBJEXT)
+tst_pmMaskBadPixels_OBJECTS = $(am_tst_pmMaskBadPixels_OBJECTS)
+tst_pmMaskBadPixels_LDADD = $(LDADD)
+am_tst_pmNonLinear_OBJECTS = tst_pmNonLinear.$(OBJEXT)
+tst_pmNonLinear_OBJECTS = $(am_tst_pmNonLinear_OBJECTS)
+tst_pmNonLinear_LDADD = $(LDADD)
+am_tst_pmSubtractBias_OBJECTS = tst_pmSubtractBias.$(OBJEXT)
+tst_pmSubtractBias_OBJECTS = $(am_tst_pmSubtractBias_OBJECTS)
+tst_pmSubtractBias_LDADD = $(LDADD)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/tst_pmFlatField.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/tst_pmMaskBadPixels.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/tst_pmNonLinear.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/tst_pmSubtractBias.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(tst_pmFlatField_SOURCES) $(tst_pmMaskBadPixels_SOURCES) \
+	$(tst_pmNonLinear_SOURCES) $(tst_pmSubtractBias_SOURCES)
+DIST_SOURCES = $(tst_pmFlatField_SOURCES) \
+	$(tst_pmMaskBadPixels_SOURCES) $(tst_pmNonLinear_SOURCES) \
+	$(tst_pmSubtractBias_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GSL_CONFIG = @GSL_CONFIG@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+tst_pmFlatField_SOURCES = tst_pmFlatField.c
+tst_pmFlatField_LDFLAGS = -L../src -lpsmodule
+tst_pmMaskBadPixels_SOURCES = tst_pmMaskBadPixels.c
+tst_pmMaskBadPixels_LDFLAGS = -L../src -lpsmodule
+tst_pmNonLinear_SOURCES = tst_pmNonLinear.c
+tst_pmNonLinear_LDFLAGS = -L../src -lpsmodule
+tst_pmSubtractBias_SOURCES = tst_pmSubtractBias.c
+tst_pmSubtractBias_LDFLAGS = -L../src -lpsmodule
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  test/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu  test/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-binPROGRAMS: $(bin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+	@list='$(bin_PROGRAMS)'; for p in $$list; do \
+	  p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+	  if test -f $$p \
+	     || test -f $$p1 \
+	  ; then \
+	    f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+	   echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+	   $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+	  else :; fi; \
+	done
+
+uninstall-binPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_PROGRAMS)'; for p in $$list; do \
+	  f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+	  echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(bindir)/$$f"; \
+	done
+
+clean-binPROGRAMS:
+	@list='$(bin_PROGRAMS)'; for p in $$list; do \
+	  f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+	  echo " rm -f $$p $$f"; \
+	  rm -f $$p $$f ; \
+	done
+tst_pmFlatField$(EXEEXT): $(tst_pmFlatField_OBJECTS) $(tst_pmFlatField_DEPENDENCIES) 
+	@rm -f tst_pmFlatField$(EXEEXT)
+	$(LINK) $(tst_pmFlatField_LDFLAGS) $(tst_pmFlatField_OBJECTS) $(tst_pmFlatField_LDADD) $(LIBS)
+tst_pmMaskBadPixels$(EXEEXT): $(tst_pmMaskBadPixels_OBJECTS) $(tst_pmMaskBadPixels_DEPENDENCIES) 
+	@rm -f tst_pmMaskBadPixels$(EXEEXT)
+	$(LINK) $(tst_pmMaskBadPixels_LDFLAGS) $(tst_pmMaskBadPixels_OBJECTS) $(tst_pmMaskBadPixels_LDADD) $(LIBS)
+tst_pmNonLinear$(EXEEXT): $(tst_pmNonLinear_OBJECTS) $(tst_pmNonLinear_DEPENDENCIES) 
+	@rm -f tst_pmNonLinear$(EXEEXT)
+	$(LINK) $(tst_pmNonLinear_LDFLAGS) $(tst_pmNonLinear_OBJECTS) $(tst_pmNonLinear_LDADD) $(LIBS)
+tst_pmSubtractBias$(EXEEXT): $(tst_pmSubtractBias_OBJECTS) $(tst_pmSubtractBias_DEPENDENCIES) 
+	@rm -f tst_pmSubtractBias$(EXEEXT)
+	$(LINK) $(tst_pmSubtractBias_LDFLAGS) $(tst_pmSubtractBias_OBJECTS) $(tst_pmSubtractBias_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst_pmFlatField.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst_pmMaskBadPixels.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst_pmNonLinear.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst_pmSubtractBias.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(ETAGS_ARGS)$$tags$$unique" \
+	  || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	     $$tags $$unique
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkdir_p) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+	for dir in "$(DESTDIR)$(bindir)"; do \
+	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+	clean-generic clean-libtool ctags distclean distclean-compile \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binPROGRAMS install-data install-data-am install-exec \
+	install-exec-am install-info install-info-am install-man \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+	pdf pdf-am ps ps-am tags uninstall uninstall-am \
+	uninstall-binPROGRAMS uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
Index: /branches/rel3/psModules/test/runTest
===================================================================
--- /branches/rel3/psModules/test/runTest	(revision 2163)
+++ /branches/rel3/psModules/test/runTest	(revision 2163)
@@ -0,0 +1,388 @@
+#!/usr/bin/perl
+#
+#  This is a perl script to execute a single test driver program.  The script
+#  will examine the return value of the test driver and capture STDOUT, STDERR
+#  to files.  If the return value of the test driver is not zero, the test is
+#  deemed a failure.  STDOUT and STDERR files will be place in a subdirectory
+#  named temp and the files will be compared with verified STDOUT, STDERR files
+#  in a subdirectory named verified.  If there are no STDOUT, STDERR files in
+#  the verified directory, the captured STDOUT, STDERR files will be scanned
+#  for words which indicate a failure.
+#
+#  Assumptions:  A verified subdirectory with STDOUT, STDERR files exists for
+#                the test driver specified in the arguements if an exact
+#                match of the streams STDOUT, STDERR is necessary.
+#
+#  Return values:
+#                 Bit mapped values
+#                 0    Test run successfull and all tests passed
+#                 1    Verified directory did not exist
+#                 2    Verified STDOUT file did not exist
+#                 4    Verified STDERR file did not exist
+#                 8    STDOUT files did not compare
+#                16    STDERR files did not compare
+#                32    Test driver doesn't exist or is not executable
+#                64    STDOUT captured contains error strings
+#               128    STDERR captured contains error strings
+#               256    Test driver did not return zero
+#
+#  SYNOSIS:  runTest testDriverName
+#
+#  $Revison:  $  $Name: not supported by cvs2svn $
+#  $Date: 2004-10-14 23:58:56 $
+#
+#  Copyright 2004 Maui High Performance Computering Center, University of Hawaii
+#
+################################################################################
+
+# Provides functions for handling long command line options
+use Getopt::Long;
+
+# Assign variables based on the presence of command line options to the script
+GetOptions(
+    "reset!"       => \$reset,
+    "resetStderr!" => \$resetStderr,
+    "resetStdout!" => \$resetStdout,
+    "help!"        => \$help
+);
+
+if ($help) {
+    print
+"Usage: runTest [--reset] [--resetStderr] [--resetStdout] testfile(s)\n\n";
+    exit(0);
+}
+
+if ($reset) {
+    $resetStderr = 1;
+    $resetStdout = 1;
+}
+
+# Initialize exit value
+$exitValue = 0;
+
+# Set up the PSLIB_ROOT environment variable if the user doesn't have it set
+if ( !$ENV{'PSLIB_ROOT'} ) {
+
+    # Use the directory directly above test
+    $PSLIB_ROOT = `cd ..;pwd`;
+
+    # Remove newline for the end of path returned
+    chomp($PSLIB_ROOT);
+
+    # Set the environment variable
+    $ENV{'PSLIB_ROOT'} = $PSLIB_ROOT;
+
+    # Display message that PSLIB_ROOT not found and set to
+    print("PSLIB_ROOT not found: set to $PSLIB_ROOT\n");
+}
+
+# Add PSLIB_ROOT/lib to LD_LIBRARY_PATH and DYLD_LIBRARY_PATH environment vars
+$ENV{'LD_LIBRARY_PATH'}   = "$ENV{'PSLIB_ROOT'}/lib:$ENV{'LD_LIBRARY_PATH'}";
+$ENV{'DYLD_LIBRARY_PATH'} = "$ENV{'PSLIB_ROOT'}/lib:$ENV{'DYLD_LIBRARY_PATH'}";
+
+# Loop through the arguements passed to the script
+foreach (@ARGV) {
+    chomp;
+    $testFile = $_;
+
+    # Check if a temp directory already exists in the current work directory
+    if ( !( -e "temp" ) ) {
+
+        # Create temp directory to store STDOUT, STDERR files during test run
+        `mkdir temp`;
+
+        # Display message of new directory created
+        print("Creating temp directory\n");
+    }
+
+    # Check if a verified directory exists in the current work directory
+    if ( !( -e "verified" ) ) {
+
+        # Display message that verified subdirectory doesn't exist
+        print("        Verified directory doesn't exist.\n");
+
+        # Exit script since the test cannot be run with verified files
+        $exitValue = 1;
+    }
+
+    # Check if the test driver file exists and is executable
+    if ( ( -e $testFile ) && ( -x $testFile ) ) {
+
+        # Display message the test driver is being executed
+        print("--- Executing test driver: $testFile\n");
+
+        # Invoke the test driver
+        system("./$testFile 1> temp/$testFile.stdout 2> temp/$testFile.stderr");
+
+        # Check the return value of the test driver.  A value other than 0
+        # indicates failure of the test driver unless the test driver is name
+        # with a leading 'a' which indicates the test driver is expecting an
+        # abort condition to terminate the driver.
+        if (   ( $? != 0 && ( $testFile !~ /^A/i ) )
+            || ( $? == 0 && ( $testFile =~ /^A/i ) ) )
+        {
+
+            # Display failure message with return value to user
+            if ( $? != 0 && ( $testFile !~ /^A/i ) ) {
+                print(
+"        Failed - Test Driver expected 0 return value (Return value $?)\n"
+                );
+            }
+            elsif ( $? == 0 && ( $testFile =~ /^A/i ) ) {
+                print(
+"        Failed - Test Driver expected abort (Return value $?)\n"
+                );
+            }
+            $exitValue |= 256;
+        }
+        else {
+
+            # Test driver succeeded.
+
+            # Create filtered version of stdout and stderr
+
+            # Open the STDOUT file for reading
+            open( OUTFILE, "< temp/$testFile.stdout" );
+
+            # Open mod file to place filtered STDOUT
+            open( MODFILE,  "> temp/$testFile.stdout.mod" );
+            open( MODFILE2, "> verified/$testFile.stdout" ) if $resetStdout;
+
+           # Replace the variable date, time and host information with constants
+            $hostname = `hostname`;
+            chop $hostname;
+            while (<OUTFILE>) {
+                s/\s+\d+:\d+:\d+\w/<TIME>/g;
+                s/\d+:\d+:\d+/<DATE>/g;
+                s/$hostname\s*/<HOST>/g;
+                s/: Line \d+/: Line <LINENO>/g;
+                s/\:\d+/\:<LINENO>/g;
+                s/allocate \d+ bytes at/allocate <N> bytes at/g;
+
+              # Filter lines with malloc.  This is an artifact of memory testing
+              # with the Mac testbed
+                if ( !m/\*\*\*\smalloc/ ) {
+                    print MODFILE ($_);
+                    print MODFILE2 ($_) if $resetStdout;
+                }
+            }
+
+            # Close mod file
+            close(MODFILE);
+            close(MODFILE2) if $resetStdout;
+
+            # Close STDERR file
+            close(OUTFILE);
+
+            # Open the STDERR file for reading
+            open( OUTFILE, "< temp/$testFile.stderr" );
+
+            # Open mod file to place filtered STDERR
+            open( MODFILE,  "> temp/$testFile.stderr.mod" );
+            open( MODFILE2, "> verified/$testFile.stderr" ) if $resetStderr;
+
+           # Replace the variable date, time and host information with constants
+            while (<OUTFILE>) {
+                s/\s+\d+:\d+:\d+\w/<TIME>/g;
+                s/\d+:\d+:\d+/<DATE>/g;
+                s/$hostname\s*/<HOST>/g;
+                s/: Line \d+/: Line <LINENO>/g;
+                s/\:\d+/\:<LINENO>/g;
+                s/allocate \d+ bytes at/allocate <N> bytes at/g;
+
+              # Filter lines with malloc.  This is an artifact of memory testing
+              # with the Mac testbed
+                if ( !m/\*\*\*\smalloc/ ) {
+                    print MODFILE ($_);
+                    print MODFILE2 ($_) if $resetStderr;
+                }
+            }
+
+            # Close mod file
+            close(MODFILE);
+            close(MODFILE2) if $resetStderr;
+
+            # Close STDERR file
+            close(OUTFILE);
+
+            # Compare STDOUT capture with verified file
+            $exitValue |= &compareStream("verified/$testFile.stdout");
+
+            # Check exit value to determine if verified file doesn't exist
+            if ( $exitValue & 2 ) {
+
+                # STDOUT verified doesn't exist.  Search STDOUT capture
+                # for strings indicating error or failure
+                $exitValue |= &errorStrSearch("$testFile.stdout");
+            }
+
+            # Compare STDERR capture with verified file
+            $exitValue |= &compareStream("verified/$testFile.stderr");
+
+            # Check exit value to determine if verified file doesn't exist
+            if ( $exitValue & 4 ) {
+
+                # STDERR verified doesn't exist.  Search STDERR capture
+                # for strings indicating error or failure
+                $exitValue |= &errorStrSearch("$testFile.stderr");
+            }
+        }
+    }
+    else {
+
+        # Since test driver doesn't exist or is not executable then display
+        # message to user.
+        print(
+"        Need to specify an executable test file within directory.\n"
+        );
+
+        # Exit value set to indicate test driver doesn't exist or not executable
+        $exitValue |= 32;
+    }
+}
+
+# Exit for the script with exit value
+# Ignore the first three bit flags in exitValue since there are not indicators
+# of a failed test
+if ( ( $exitValue >> 3 ) != 0 ) {
+    print("Test failed - return status = $exitValue\n\n");
+}
+else {
+    print("Test successful\n\n");
+}
+exit($exitValue);
+
+################################################################################
+#
+#  SUBROUTINE: errorStrSearch
+#
+#      Description:  This subroutine will search the file specified in its
+#                    parameter for error strings and if they do exists
+#                    the appropriate value will be returned.
+#
+#      Parameter(s): fileName - input file to search for strings
+#
+#      Return:   0  -  No error strings found
+#               64  -  Error strings found in STDOUT
+#              128  -  Error strings found in STDERR
+#
+###############################################################################
+
+sub errorStrSearch {
+    local ($fileName)  = @_;
+    local ($returnVal) = 0;
+
+    # Open the captured file
+    open( CAPT_FILE, "<temp/$fileName" );
+
+    # Scan through all the lines of the file searching for error strings
+    while (<CAPT_FILE>) {
+        if (   m/FAIL/i
+            || m/FAULT/i
+            || m/ERROR/i
+            || m/Not Found/i
+            || m/SIGNAL/i
+            || m/NO SUCH FILE/i
+            || m/\|E\|/i
+            || m/\|A\|/i )
+        {
+            if ( $fileName =~ m/out/ ) {
+                print(
+                    "        Failed - File $fileName contains error strings.\n"
+                );
+                $returnVal = 64;
+            }
+            elsif ( $fileName =~ m/err/ ) {
+                print(
+                    "        Failed - File $fileName contains error strings.\n"
+                );
+                $returnVal = 128;
+            }
+            last;
+        }
+    }
+
+    # Close the capture file
+    close(CAPT_FILE);
+
+    # Return the return value
+    return ($returnVal);
+}
+
+################################################################################
+#
+#  SUBROUTINE: compareStream
+#
+#      Description:  This subroutine will compare the captured stream file with
+#                    a file in the verified directory if one exists.
+#
+#      Parameter(s): streamFile - input file to compare
+#
+#      Return:   0  -  Compare successful
+#                2  -  STDOUT verified file doesn't exist
+#                4  -  STDERR verified file doesn't exist
+#                8  -  STDOUT verified file doesn't compare
+#               16  -  STDERR verified file doesn't compare
+#
+###############################################################################
+
+sub compareStream {
+    local ($streamFile) = @_;
+    local ($returnVal)  = 0;
+    local ($tempFile)   = "";
+
+    # Check for existence of verified STD stream files
+    if ( !( -e $streamFile ) ) {
+
+        # Display message to user that verified STDOUT file doesn't exist
+        print("        File $streamFile doesn't exist.\n");
+
+        # Set exit value bit 1 to indicate proper failure
+        if ( $streamFile =~ /out$/ ) {
+            $returnVal |= 2;
+        }
+        elsif ( $streamFile =~ /err$/ ) {
+            $returnVal |= 4;
+        }
+    }
+    else {
+
+        # Verified STD stream file exists
+
+        # Create name of the temp file to compare
+        $tempFile = $streamFile;
+        $tempFile =~ s/verified/temp/;
+        $tempFile = $tempFile . ".mod";
+
+        # Perform difference on the STD stream files
+        $diffstdout = `diff $streamFile $tempFile`;
+
+        # Check the return value of the difference
+        if ( $? != 0 ) {
+
+            # Difference of STD stream files failed
+
+            # Check for STDOUT in file name to convey appropirate return value
+            if ( $streamFile =~ /out$/ ) {
+
+                # Display message of the failure of difference to user
+                print("        Failed - STDOUT difference\n$diffstdout\n");
+
+                # Exit value to indicate STDOUT did not compare
+                $returnVal |= 8;
+            }
+            elsif ( $streamFile =~ /err$/ ) {
+
+                # Display message of the failure of difference to user
+                print("        Failed - STDERR difference\n$diffstdout\n");
+
+                # Exit value to indicate STDERR did not compare
+                $returnVal |= 16;
+            }
+        }
+    }
+
+    # Return the result of the compare
+    return ($returnVal);
+}
+
Index: /branches/rel3/psModules/test/tst_pmFlatField.c
===================================================================
--- /branches/rel3/psModules/test/tst_pmFlatField.c	(revision 2163)
+++ /branches/rel3/psModules/test/tst_pmFlatField.c	(revision 2163)
@@ -0,0 +1,233 @@
+/** @file tst_pmFlatField.c
+ *
+ *  @brief Contains the tests for pmFlatField.c:
+ *
+ *    Test A - Divide input image by flat image
+ *    Test B - Mask flat image data
+ *    Test C - Mask flat image data starting with non-null mask
+ *    Test E - Attempt to use null input image
+ *    Test F - Attempt tp use null flat image
+ *    Test G - Attempt to use input image bigger than flat image
+ *    Test H - Attempt to use input image mask bigger than flat image
+ *    Test I - Attempt to use offset greater than input image
+ *    Test J - Attempt to use complex input image
+ *    Test K - Attempt to use complex flat image
+ *    Test L - Attempt to use non-equal input and flat image types
+ *    Test M - Attempt to use non-mask type mask image
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.1 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-09-24 23:42:28 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+
+#include "psTest.h"
+#include "pslib.h"
+#include "pmFlatField.h"
+
+
+#define PRINT_MATRIX(IMAGE,TYPE,STRING)                                                                      \
+printf(STRING);                                                                                              \
+printf("\n");                                                                                                \
+for(int i=IMAGE->numRows-1; i>-1; i--) {                                                                     \
+    for(int j=0; j<IMAGE->numCols; j++) {                                                                    \
+        if(PS_IS_PSELEMTYPE_COMPLEX(IMAGE->type.type)) {                                                     \
+            printf("%f+%fi ", creal(IMAGE->data.TYPE[i][j]), cimag(IMAGE->data.TYPE[i][j]));                 \
+        } else if(PS_IS_PSELEMTYPE_INT(IMAGE->type.type)) {                                                  \
+            printf("%d ", (int)IMAGE->data.TYPE[i][j]);                                                      \
+        } else {                                                                                             \
+            printf("%f ", (double)IMAGE->data.TYPE[i][j]);                                                   \
+        }                                                                                                    \
+    }                                                                                                        \
+    printf("\n");                                                                                            \
+}                                                                                                            \
+printf("\n");
+
+
+#define CREATE_AND_SET_IMAGE(NAME,TYPE,VALUE,NROWS,NCOLS)                                                    \
+psImage *NAME = (psImage*)psImageAlloc(NCOLS,NROWS,PS_TYPE_##TYPE);                                          \
+for(int i=0; i<NAME->numRows; i++) {                                                                         \
+    for(int j=0; j<NAME->numCols; j++) {                                                                     \
+        NAME->data.TYPE[i][j] = VALUE;                                                                       \
+    }                                                                                                        \
+}
+
+
+static int testFlatField(void);
+
+
+testDescription tests[] = {
+                              {testFlatField, 884, "pmFlatField", 0, false},
+                              {NULL}
+                          };
+
+
+int main(int argc, char* argv[])
+{
+    return !runTestSuite(stderr, "Test Point Driver", tests, argc, argv);
+}
+
+
+int testFlatField( void )
+{
+    // Test A - Divide input image by flat image
+    printPositiveTestHeader(stdout, "pmFlatField", "Test A - Divide input image by flat image");
+    CREATE_AND_SET_IMAGE(inImage,F64,6.0,3,3)
+    psReadout *inReadout  = psReadoutAlloc(0, 0, inImage);
+    PRINT_MATRIX(inImage,F64,"Input image:");
+    CREATE_AND_SET_IMAGE(flatImage1,F64,2.0,3,3)
+    psReadout *flatReadout  = psReadoutAlloc(0, 0, flatImage1);
+    PRINT_MATRIX(flatImage1,F64,"Flat image:");
+    pmFlatField(inReadout, flatReadout);
+    PRINT_MATRIX(inImage,F64, "Resulting image:");
+    printFooter(stdout, "pmFlatField", "Test A - Divide input image by flat image", true);
+    printf("\n\n\n");
+
+
+    // Test B - Mask flat image data
+    printPositiveTestHeader(stdout, "pmFlatField", "Test B - Mask flat image data");
+    PRINT_MATRIX(inImage, F64, "Input image:");
+    CREATE_AND_SET_IMAGE(flatImage2,F64,0.0,3,3)
+    PRINT_MATRIX(flatImage2, F64, "Flat image:");
+    flatReadout->image = flatImage2;
+    pmFlatField(inReadout, flatReadout);
+    PRINT_MATRIX(inReadout->mask, PS_TYPE_MASK_DATA, "Resulting mask:");
+    printFooter(stdout, "pmFlatField", "Test B - Mask flat image data", true);
+    printf("\n\n\n");
+
+
+    // Test C - Mask flat image data starting with non-null mask
+    printPositiveTestHeader(stdout, "pmFlatField", "Test C - Mask flat image data starting with non-null mask");
+    PRINT_MATRIX(inImage, F64, "Input image:");
+    flatImage2->data.F64[0][0] = 1.0;
+    PRINT_MATRIX(flatImage2, F64, "Flat image:");
+    CREATE_AND_SET_IMAGE(mask1,U8,0,3,3);
+    psFree(inReadout->mask);
+    inReadout->mask = mask1;
+    pmFlatField(inReadout, flatReadout);
+    PRINT_MATRIX(inReadout->mask, PS_TYPE_MASK_DATA,"Resulting mask:");
+    printFooter(stdout, "pmFlatField", "Test C - Mask flat image data starting with non-null mask", true);
+    printf("\n\n\n");
+
+
+    // Test D - Attempt to use null flat readout
+    printNegativeTestHeader(stdout,"pmFlatField", "Test D - Attempt to use null flat readout",
+                            "Null not allowed for flat readout", 0);
+    pmFlatField(inReadout, NULL);
+    printFooter(stdout, "pmFlatField", "Test D - Attempt to use null flat readout", true);
+    printf("\n\n\n");
+
+
+    // Test E - Attempt to use null input image
+    printNegativeTestHeader(stdout,"pmFlatField", "Test E - Attempt to use null input image",
+                            "Null not allowed for input image", 0);
+    psImage *temp = inReadout->image;
+    inReadout->image = NULL;
+    pmFlatField(inReadout, flatReadout);
+    inReadout->image = temp;
+    printFooter(stdout, "pmFlatField", "Test E - Attempt to use null input image", true);
+    printf("\n\n\n");
+
+
+    // Test F - Attempt tp use null flat image
+    printNegativeTestHeader(stdout,"pmFlatField", "Test F - Attempt tp use null flat image",
+                            "Null not allowed for flat image", 0);
+    temp = flatReadout->image;
+    flatReadout->image = NULL;
+    pmFlatField(inReadout, flatReadout);
+    flatReadout->image = temp;
+    printFooter(stdout, "pmFlatField", "Test F - Attempt tp use null flat image", true);
+    printf("\n\n\n");
+
+
+    // Test G - Attempt to use input image bigger than flat image
+    printNegativeTestHeader(stdout,"pmFlatField", "Test G - Attempt to use input image bigger than flat image",
+                            "Input image size exceeds that of flat image", 0);
+    CREATE_AND_SET_IMAGE(smallFlat,F64,0.0,2,2);
+    temp = flatReadout->image;
+    flatReadout->image = smallFlat;
+    pmFlatField(inReadout, flatReadout);
+    flatReadout->image = temp;
+    printFooter(stdout, "pmFlatField", "Test G - Attempt to use input image bigger than flat image", true);
+    printf("\n\n\n");
+
+
+    // Test H - Attempt to use input image mask bigger than flat image
+    printNegativeTestHeader(stdout,"pmFlatField", "Test H - Attempt to use input image mask bigger than flat image",
+                            "Input image mask size exceeds that of flat image", 0);
+    CREATE_AND_SET_IMAGE(largeMask,F64,0.0,4,4);
+    temp = inReadout->mask;
+    inReadout->mask = largeMask;
+    pmFlatField(inReadout, flatReadout);
+    inReadout->mask = temp;
+    printFooter(stdout, "pmFlatField", "Test H - Attempt to use input image mask bigger than flat image", true);
+    printf("\n\n\n");
+
+
+    // Test I - Attempt to use offset greater than input image
+    printNegativeTestHeader(stdout,"pmFlatField", "Test I - Attempt to use offset greater than input image",
+                            "Total offset >= input image size", 0);
+    *(int*)&inReadout->col0 = 50;
+    *(int*)&inReadout->row0 = 50;
+    pmFlatField(inReadout, flatReadout);
+    *(int*)&inReadout->col0 = 0;
+    *(int*)&inReadout->row0 = 0;
+    printFooter(stdout, "pmFlatField", "Test I - Attempt to use offset greater than input image", true);
+    printf("\n\n\n");
+
+
+    // Test J - Attempt to use complex input image
+    printNegativeTestHeader(stdout,"pmFlatField", "Test J - Attempt to use complex input image",
+                            "Complex types not allowed for input image", 0);
+    *(psElemType* ) & inReadout->image->type.type = PS_TYPE_C64;
+    pmFlatField(inReadout, flatReadout);
+    *(psElemType* ) & inReadout->image->type.type = PS_TYPE_F64;
+    printFooter(stdout, "pmFlatField", "Test J - Attempt to use complex input image", true);
+    printf("\n\n\n");
+
+
+    // Test K - Attempt to use complex flat image
+    printNegativeTestHeader(stdout,"pmFlatField", "Test K - Attempt to use complex flat image",
+                            "Complex types not allowed for flat image", 0);
+    *(psElemType* ) & flatReadout->image->type.type = PS_TYPE_C64;
+    pmFlatField(inReadout, flatReadout);
+    *(psElemType* ) & flatReadout->image->type.type = PS_TYPE_F64;
+    printFooter(stdout, "pmFlatField", "Test K - Attempt to use complex flat image", true);
+    printf("\n\n\n");
+
+
+    // Test L - Attempt to use non-equal input and flat image types
+    printNegativeTestHeader(stdout,"pmFlatField", "Test L - Attempt to use non-equal input and flat image types",
+                            "Input and flat image types differ", 0);
+    *(psElemType* ) & flatReadout->image->type.type = PS_TYPE_F32;
+    pmFlatField(inReadout, flatReadout);
+    *(psElemType* ) & flatReadout->image->type.type = PS_TYPE_F64;
+    printFooter(stdout, "pmFlatField", "Test L - Attempt to use non-equal input and flat image types", true);
+    printf("\n\n\n");
+
+
+    // Test M - Attempt to use non-mask type mask image
+    printNegativeTestHeader(stdout,"pmFlatField", "Test M - Attempt to use non-mask type mask image",
+                            "Mask must be PS_TYPE_MASK type", 0);
+    *(psElemType* ) & inReadout->mask->type.type = PS_TYPE_F32;
+    pmFlatField(inReadout, flatReadout);
+    *(psElemType* ) & inReadout->mask->type.type = PS_TYPE_MASK;
+    printFooter(stdout, "pmFlatField", "Test M - Attempt to use non-mask type mask image", true);
+    printf("\n\n\n");
+
+
+    // Free memory
+    psFree(inReadout);
+    psFree(flatReadout);
+    psFree(inImage);
+    psFree(flatImage1);
+    psFree(flatImage1);
+    psFree(smallFlat);
+    psFree(largeMask);
+
+    return 0;
+}
+
Index: /branches/rel3/psModules/test/tst_pmMaskBadPixels.c
===================================================================
--- /branches/rel3/psModules/test/tst_pmMaskBadPixels.c	(revision 2163)
+++ /branches/rel3/psModules/test/tst_pmMaskBadPixels.c	(revision 2163)
@@ -0,0 +1,269 @@
+/** @file tst_pmMaskBadPixels.c
+ *
+ *  @brief Contains the tests for pmMaskBadPixels:
+ *
+ *    Test A - Create mask based on maskVal argument
+ *    Test B - Create mask based on saturation argument
+ *    Test C - Create mask based on growVal and grow arguments
+ *    Test D - Auto Create mask based on maskVal argument
+ *    Test E - Attempt to use null mask
+ *    Test F - Attempt tp use null input image
+ *    Test G - Attempt to use input image bigger than mask
+ *    Test H - Attempt to use input image mask bigger than mask
+ *    Test I - Attempt to use offset greater than input image
+ *    Test J - Attempt to use complex input image
+ *    Test K - Attempt to use non-mask type mask image
+ *
+ *  @author Ross Harman, MHPCC
+ *
+ *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 23:52:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+
+#include "psTest.h"
+#include "pslib.h"
+#include "pmMaskBadPixels.h"
+
+
+#define PRINT_MATRIX(IMAGE,TYPE,STRING)                                                                      \
+printf(STRING);                                                                                              \
+printf("\n");                                                                                                \
+for(int i=IMAGE->numRows-1; i>-1; i--) {                                                                     \
+    for(int j=0; j<IMAGE->numCols; j++) {                                                                    \
+        if(PS_IS_PSELEMTYPE_COMPLEX(IMAGE->type.type)) {                                                     \
+            printf("%f+%fi ", creal(IMAGE->data.TYPE[i][j]), cimag(IMAGE->data.TYPE[i][j]));                 \
+        } else if(PS_IS_PSELEMTYPE_INT(IMAGE->type.type)) {                                                  \
+            printf("%d", (int)IMAGE->data.TYPE[i][j]);                                                       \
+        } else {                                                                                             \
+            printf("%f", (double)IMAGE->data.TYPE[i][j]);                                                    \
+        }                                                                                                    \
+    }                                                                                                        \
+    printf("\n");                                                                                            \
+}                                                                                                            \
+printf("\n");
+
+
+#define CREATE_AND_SET_IMAGE(NAME,TYPE,VALUE,NROWS,NCOLS)                                                    \
+psImage *NAME = (psImage*)psImageAlloc(NCOLS,NROWS,PS_TYPE_##TYPE);                                          \
+for(int i=0; i<NAME->numRows; i++) {                                                                         \
+    for(int j=0; j<NAME->numCols; j++) {                                                                     \
+        NAME->data.TYPE[i][j] = VALUE;                                                                       \
+    }                                                                                                        \
+}
+
+
+static int testMaskBadPixels1(void);
+static int testMaskBadPixels2(void);
+static int testMaskBadPixels3(void);
+static int testMaskBadPixels4(void);
+static int testMaskBadPixels5(void);
+static int testMaskBadPixels6(void);
+static int testMaskBadPixels7(void);
+static int testMaskBadPixels8(void);
+static int testMaskBadPixels9(void);
+static int testMaskBadPixels10(void);
+static int testMaskBadPixels11(void);
+
+
+testDescription tests[] = {
+                              {testMaskBadPixels1, 885, "pmMaskBadPixels - Create mask based on maskVal argument", 0, false},
+                              {testMaskBadPixels2, 885, "pmMaskBadPixels - Create mask based on saturation argument", 0, false},
+                              {testMaskBadPixels3, 885, "pmMaskBadPixels - Create mask based on growVal and grow arguments", 0, false},
+                              {testMaskBadPixels4, 885, "pmMaskBadPixels - Auto create mask based on maskVal argument", 0, false},
+                              {testMaskBadPixels5, 885, "pmMaskBadPixels - Attempt to use null mask", 0, false},
+                              {testMaskBadPixels6, 885, "pmMaskBadPixels - Attempt tp use null input image", 0, false},
+                              {testMaskBadPixels7, 885, "pmMaskBadPixels - Attempt to use input image bigger than mask", 0, false},
+                              {testMaskBadPixels8, 885, "pmMaskBadPixels - Attempt to use input image mask bigger than mask", 0, false},
+                              {testMaskBadPixels9, 885, "pmMaskBadPixels - Attempt to use offset greater than input image", 0, false},
+                              {testMaskBadPixels10, 885, "pmMaskBadPixels - Attempt to use complex input image", 0, false},
+                              {testMaskBadPixels11, 885, "pmMaskBadPixels - Attempt to use non-mask type mask image", 0, false},
+                              {NULL}
+                          };
+
+
+int main(int argc, char* argv[])
+{
+    return !runTestSuite(stderr, "Test Point Driver", tests, argc, argv);
+}
+
+
+int testMaskBadPixels1( void )
+{
+    // Test A - Create mask based on maskVal argument
+    CREATE_AND_SET_IMAGE(inImage1,F64,0,50,50);
+    CREATE_AND_SET_IMAGE(mask1,U8,0,50,50)
+    psReadout *inReadout = psReadoutAlloc(0, 0, inImage1);
+    mask1->data.PS_TYPE_MASK_DATA[24][24]=1;
+    PRINT_MATRIX(mask1, U8, "Data mask:");
+    pmMaskBadPixels(inReadout, mask1, 1, 100.0, 0, 0);
+    PRINT_MATRIX(inReadout->mask, U8, "Resulting mask:");
+    psFree(mask1);
+    psFree(inReadout);
+    psFree(inImage1);
+
+    return 0;
+}
+
+int testMaskBadPixels2( void )
+{
+    // Test B - Create mask based on saturation argument
+    CREATE_AND_SET_IMAGE(inImage2,F64,150.0,50,50);
+    CREATE_AND_SET_IMAGE(mask2,U8,0,50,50)
+    psReadout *inReadout2 = psReadoutAlloc(0, 0, inImage2);
+    PRINT_MATRIX(mask2, U8, "Data mask:");
+    pmMaskBadPixels(inReadout2, mask2, 0, 100.0, 0, 0);
+    PRINT_MATRIX(inReadout2->mask, U8, "Resulting mask:");
+    psFree(mask2);
+    psFree(inReadout2);
+    psFree(inImage2);
+
+    return 0;
+}
+
+int testMaskBadPixels3( void )
+{
+    // Test C - Create mask based on growVal and grow arguments
+    CREATE_AND_SET_IMAGE(inImage3,F64,50.0,50,50);
+    CREATE_AND_SET_IMAGE(mask3,U8,0,50,50)
+    psReadout *inReadout3 = psReadoutAlloc(0, 0, inImage3);
+    mask3->data.PS_TYPE_MASK_DATA[24][24]=1;
+    mask3->data.PS_TYPE_MASK_DATA[4][3]=1;
+    mask3->data.PS_TYPE_MASK_DATA[4][46]=1;
+    PRINT_MATRIX(mask3, U8, "Data mask:");
+    pmMaskBadPixels(inReadout3, mask3, 0, 100.0, 1, 10);
+    PRINT_MATRIX(inReadout3->mask, U8, "Resulting mask:");
+    psFree(mask3);
+    psFree(inReadout3);
+    psFree(inImage3);
+
+    return 0;
+}
+
+int testMaskBadPixels4( void )
+{
+    // Test D - Auto Create mask based on maskVal argument
+    CREATE_AND_SET_IMAGE(inImage4,F64,50.0,50,50);
+    CREATE_AND_SET_IMAGE(mask4,U8,0,50,50)
+    CREATE_AND_SET_IMAGE(mask4i,U8,0,50,50)
+    psReadout *inReadout4 = psReadoutAlloc(0, 0, inImage4);
+    inReadout4->mask = mask4i;
+    mask4->data.PS_TYPE_MASK_DATA[24][24]=1;
+    PRINT_MATRIX(mask4, U8, "Data mask:");
+    pmMaskBadPixels(inReadout4, mask4, 0, 100.0, 1, 10);
+    PRINT_MATRIX(inReadout4->mask, U8, "Resulting mask:");
+    psFree(mask4);
+    psFree(inReadout4);
+    psFree(inImage4);
+
+    return 0;
+}
+
+int testMaskBadPixels5( void )
+{
+    // Test E - Attempt to use null mask
+    CREATE_AND_SET_IMAGE(inImage5,F64,50.0,50,50);
+    psReadout *inReadout5 = psReadoutAlloc(0, 0, inImage5);
+    pmMaskBadPixels(inReadout5, NULL, 0, 100.0, 1, 10);
+    psFree(inReadout5);
+    psFree(inImage5);
+
+    return 0;
+}
+
+int testMaskBadPixels6( void )
+{
+    // Test F - Attempt tp use null input image
+    CREATE_AND_SET_IMAGE(mask6,U8,0,50,50)
+    psReadout *inReadout6 = psReadoutAlloc(0, 0, NULL);
+    inReadout6->mask = mask6;
+    pmMaskBadPixels(inReadout6, mask6, 0, 100.0, 1, 10);
+    psFree(inReadout6);
+
+    return 0;
+}
+
+int testMaskBadPixels7( void )
+{
+    // Test G - Attempt to use input image bigger than mask
+    CREATE_AND_SET_IMAGE(inImage7,F64,0.0,60,60);
+    CREATE_AND_SET_IMAGE(mask7,U8,0,50,50)
+    CREATE_AND_SET_IMAGE(mask7i,U8,0,50,50)
+    psReadout *inReadout7 = psReadoutAlloc(0, 0, inImage7);
+    inReadout7->mask = mask7i;
+    pmMaskBadPixels(inReadout7, mask7, 0, 100.0, 1, 10);
+    psFree(mask7);
+    psFree(inReadout7);
+    psFree(inImage7);
+
+    return 0;
+}
+
+int testMaskBadPixels8( void )
+{
+    // Test H - Attempt to use input image mask bigger than mask
+    CREATE_AND_SET_IMAGE(inImage8,F64,0.0,50,50);
+    CREATE_AND_SET_IMAGE(mask8,U8,0,50,50)
+    CREATE_AND_SET_IMAGE(mask8i,U8,0,60,60)
+    psReadout *inReadout8 = psReadoutAlloc(0, 0, inImage8);
+    inReadout8->mask = mask8i;
+    pmMaskBadPixels(inReadout8, mask8, 0, 100.0, 1, 10);
+    psFree(mask8);
+    psFree(inReadout8);
+    psFree(inImage8);
+
+    return 0;
+}
+
+int testMaskBadPixels9( void )
+{
+    // Test I - Attempt to use offset greater than input image
+    CREATE_AND_SET_IMAGE(inImage9,F64,0.0,50,50);
+    CREATE_AND_SET_IMAGE(mask9,U8,0,50,50)
+    CREATE_AND_SET_IMAGE(mask9i,U8,0,50,50)
+    psReadout *inReadout9 = psReadoutAlloc(0, 0, inImage9);
+    inReadout9->mask = mask9i;
+    *(int*)&inReadout9->col0 = 150;
+    *(int*)&inReadout9->row0 = 150;
+    pmMaskBadPixels(inReadout9, mask9, 0, 100.0, 1, 10);
+    psFree(mask9);
+    psFree(inReadout9);
+    psFree(inImage9);
+
+    return 0;
+}
+
+int testMaskBadPixels10( void )
+{
+    // Test J - Attempt to use complex input image
+    CREATE_AND_SET_IMAGE(inImage10,C64,50.0,50,50);
+    CREATE_AND_SET_IMAGE(mask10,U8,0,50,50)
+    CREATE_AND_SET_IMAGE(mask10i,U8,0,50,50)
+    psReadout *inReadout10 = psReadoutAlloc(0, 0, inImage10);
+    inReadout10->mask = mask10i;
+    pmMaskBadPixels(inReadout10, mask10, 0, 100.0, 1, 10);
+    psFree(mask10);
+    psFree(inReadout10);
+    psFree(inImage10);
+
+    return 0;
+}
+
+int testMaskBadPixels11( void )
+{
+    // Test K - Attempt to use non-mask type mask image
+    CREATE_AND_SET_IMAGE(inImage11,F64,50.0,50,50);
+    CREATE_AND_SET_IMAGE(mask11,F64,0,50,50)
+    CREATE_AND_SET_IMAGE(mask11i,U8,0,50,50)
+    psReadout *inReadout11 = psReadoutAlloc(0, 0, inImage11);
+    inReadout11->mask = mask11i;
+    pmMaskBadPixels(inReadout11, mask11, 0, 100.0, 1, 10);
+    psFree(mask11);
+    psFree(inReadout11);
+    psFree(inImage11);
+
+    return 0;
+}
+
Index: /branches/rel3/psModules/test/tst_pmNonLinear.c
===================================================================
--- /branches/rel3/psModules/test/tst_pmNonLinear.c	(revision 2163)
+++ /branches/rel3/psModules/test/tst_pmNonLinear.c	(revision 2163)
@@ -0,0 +1,141 @@
+/** @file tst_pmFlatField.c
+ *
+ *  @brief Contains the tests for pmNonLinear.c:
+ *
+ * test00: This code will create a simple polynomial, and call
+ * pmNonLinearityPolynomial() for a variety of image sizes [(1, 1), (1,
+ * N), (N, 1), (N, N)].  
+ *
+ * test01: This code will create simple table lookup vectors, and call
+ * pmNonLinearityPolynomial() for a variety of image sizes [(1, 1), (1,
+ * N), (N, 1), (N, N)].  
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-14 23:52:09 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "psTest.h"
+#include "pslib.h"
+#include "pmNonLinear.h"
+static int test00(void);
+static int test01(void);
+testDescription tests[] = {
+                              {test00, 000, "pmNonLinearityPolynomial", 0, false},
+                              {test01, 000, "pmNonLinearityLookup", 0, false},
+                              {NULL}
+                          };
+
+
+int main(int argc, char* argv[])
+{
+    return !runTestSuite(stderr, "Test Point Driver", tests, argc, argv);
+}
+
+#define NUM_ROWS 8
+#define NUM_COLS 8
+int doNonLinearityPolynomialTest(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+    psImage *myImage = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc(numCols, numRows, myImage);
+    psPolynomial1D *myPoly = psPolynomial1DAlloc(2, PS_POLYNOMIAL_ORD);
+    myPoly->coeff[1] = 1.0;
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+
+    myReadout = pmNonLinearityPolynomial(myReadout, myPoly);
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            expect = psPolynomial1DEval((float) (i + j), myPoly);
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(myPoly);
+    return(testStatus);
+}
+
+int test00( void )
+{
+    int testStatus = 0;
+
+    testStatus |= doNonLinearityPolynomialTest(1, 1);
+    testStatus |= doNonLinearityPolynomialTest(NUM_COLS, 1);
+    testStatus |= doNonLinearityPolynomialTest(1, NUM_ROWS);
+    testStatus |= doNonLinearityPolynomialTest(NUM_COLS, NUM_ROWS);
+
+    return(testStatus);
+}
+
+int doNonLinearityLookupTest(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+    int tableSize = PS_MAX(numCols, numRows)*2;
+    psImage *myImage = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc(numCols, numRows, myImage);
+    psVector *in = psVectorAlloc(tableSize, PS_TYPE_F32);
+    psVector *out = psVectorAlloc(tableSize, PS_TYPE_F32);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+        }
+    }
+
+    for (i=0;i<tableSize;i++) {
+        in->data.F32[i] = (float) i;
+        out->data.F32[i] = (float) (2 * i);
+    }
+
+    myReadout = pmNonLinearityLookup(myReadout, in, out);
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            expect = (float) (2 * (i + j));
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(in);
+    psFree(out);
+    return(testStatus);
+}
+
+int test01( void )
+{
+    int testStatus = 0;
+
+    testStatus |= doNonLinearityLookupTest(1, 1);
+    testStatus |= doNonLinearityLookupTest(NUM_COLS, 1);
+    testStatus |= doNonLinearityLookupTest(1, NUM_ROWS);
+    testStatus |= doNonLinearityLookupTest (NUM_COLS, NUM_ROWS);
+
+    return(testStatus);
+}
Index: /branches/rel3/psModules/test/tst_pmSubtractBias.c
===================================================================
--- /branches/rel3/psModules/test/tst_pmSubtractBias.c	(revision 2163)
+++ /branches/rel3/psModules/test/tst_pmSubtractBias.c	(revision 2163)
@@ -0,0 +1,293 @@
+/** @file tst_pmFlatField.c
+ *
+ *  @brief Contains the tests for pmSubtractBias.c:
+ *
+ * test00: This code will subtract full bias frames from the input image.
+ * test01: Multiple overscan regions, calculate a scalar statistic for
+ *  each, then subtract from the input image.
+ * test02: Calculate a column overscan vector and subtract it from each
+ *  column in the input image.
+ * test03: Calculate a row overscan vector and subtract it from each
+ *  row in the input image.
+ *
+ *
+ *  @author GLG, MHPCC
+ *
+ *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
+ *  @date $Date: 2004-10-15 02:15:34 $
+ *
+ *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
+ */
+
+#include "psTest.h"
+#include "pslib.h"
+#include "pmSubtractBias.h"
+static int test00(void);
+static int test01(void);
+static int test02(void);
+static int test03(void);
+testDescription tests[] = {
+                              {test00, 000, "pmSubtractBias", 0, false},
+                              {test01, 000, "pmSubtractBias", 0, false},
+                              {test02, 000, "pmSubtractBias", 0, false},
+                              {test03, 000, "pmSubtractBias", 0, false},
+                              {NULL}
+                          };
+
+
+int main(int argc, char* argv[])
+{
+    return !runTestSuite(stderr, "Test Point Driver", tests, argc, argv);
+}
+
+#define NUM_ROWS 4
+#define NUM_COLS 4
+int doSubtractBiasFullFrame(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage2 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc(numCols, numRows, tmpImage1);
+    psReadout *myBias = psReadoutAlloc(numCols, numRows, tmpImage2);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+            myBias->image->data.F32[i][j] = 1.0;
+        }
+    }
+
+    myReadout = pmSubtractBias(myReadout, NULL, NULL, PM_OVERSCAN_NONE, NULL,
+                               0, PM_FIT_NONE, myBias);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            expect = ((float) (i + j)) - 1.0;
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(myBias);
+    return(testStatus);
+}
+
+
+int test00( void )
+{
+    int testStatus = 0;
+
+    testStatus |= doSubtractBiasFullFrame(1, 1);
+    testStatus |= doSubtractBiasFullFrame(NUM_COLS, 1);
+    testStatus |= doSubtractBiasFullFrame(1, NUM_ROWS);
+    testStatus |= doSubtractBiasFullFrame(NUM_COLS, NUM_ROWS);
+
+    return(testStatus);
+}
+
+int doSubtractFullOverscans(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage2 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage3 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage4 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc(numCols, numRows, tmpImage1);
+    psList *list;
+    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+            tmpImage2->data.F32[i][j] = 3.0;
+            tmpImage3->data.F32[i][j] = 4.0;
+            tmpImage4->data.F32[i][j] = 5.0;
+        }
+    }
+    list = psListAlloc(tmpImage2);
+    psListAdd(list, PS_LIST_HEAD, tmpImage3);
+    psListAdd(list, PS_LIST_HEAD, tmpImage4);
+
+    myReadout = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_ALL, stat,
+                               0, PM_FIT_NONE, NULL);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            expect = ((float) (i + j)) - 12.0;
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(tmpImage2);
+    psFree(tmpImage3);
+    psFree(tmpImage4);
+    psFree(stat);
+    psFree(list);
+
+    return(testStatus);
+}
+
+int test01( void )
+{
+    int testStatus = 0;
+
+    testStatus |= doSubtractFullOverscans(1, 1);
+    testStatus |= doSubtractFullOverscans(1, NUM_ROWS);
+    testStatus |= doSubtractFullOverscans(NUM_COLS, 1);
+    testStatus |= doSubtractFullOverscans(NUM_COLS, NUM_ROWS);
+
+    return(testStatus);
+}
+
+int doSubtractFullOverscanColumns(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage2 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage3 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage4 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc(numCols, numRows, tmpImage1);
+    psList *list;
+    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+            tmpImage2->data.F32[i][j] = 3.0;
+            tmpImage3->data.F32[i][j] = 4.0;
+            tmpImage4->data.F32[i][j] = 5.0;
+        }
+    }
+    list = psListAlloc(tmpImage2);
+    psListAdd(list, PS_LIST_HEAD, tmpImage3);
+    psListAdd(list, PS_LIST_HEAD, tmpImage4);
+
+    printPositiveTestHeader(stdout, "pmSubtractBias", "Column Overscans");
+
+    myReadout = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_COLUMNS, stat,
+                               0, PM_FIT_NONE, NULL);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            expect = ((float) (i + j)) - 12.0;
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(tmpImage2);
+    psFree(tmpImage3);
+    psFree(tmpImage4);
+    psFree(stat);
+    psFree(list);
+
+    printFooter(stdout, "pmSubtractBias", "Column Overscans", true);
+    return(testStatus);
+}
+
+int test02( void )
+{
+    int testStatus = 0;
+
+    testStatus |= doSubtractFullOverscanColumns(1, 1);
+    testStatus |= doSubtractFullOverscanColumns(1, NUM_ROWS);
+    testStatus |= doSubtractFullOverscanColumns(NUM_COLS, 1);
+    testStatus |= doSubtractFullOverscanColumns(NUM_COLS, NUM_ROWS);
+
+    return(testStatus);
+}
+
+int doSubtractFullOverscanRows(int numCols, int numRows)
+{
+    int i;
+    int j;
+    float actual;
+    float expect;
+    int testStatus = 0;
+    psImage *tmpImage1 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage2 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage3 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psImage *tmpImage4 = psImageAlloc(numCols, numRows, PS_TYPE_F32);
+    psReadout *myReadout = psReadoutAlloc(numCols, numRows, tmpImage1);
+    psList *list;
+    psStats *stat = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            myReadout->image->data.F32[i][j] = (float) (i + j);
+            tmpImage2->data.F32[i][j] = 3.0;
+            tmpImage3->data.F32[i][j] = 4.0;
+            tmpImage4->data.F32[i][j] = 5.0;
+        }
+    }
+    list = psListAlloc(tmpImage2);
+    psListAdd(list, PS_LIST_HEAD, tmpImage3);
+    psListAdd(list, PS_LIST_HEAD, tmpImage4);
+
+    printPositiveTestHeader(stdout, "pmSubtractBias", "Row Overscans");
+
+    myReadout = pmSubtractBias(myReadout, NULL, list, PM_OVERSCAN_ROWS, stat,
+                               0, PM_FIT_NONE, NULL);
+
+    for (i=0;i<numRows;i++) {
+        for (j=0;j<numCols;j++) {
+            expect = ((float) (i + j)) - 12.0;
+            actual = myReadout->image->data.F32[i][j];
+            if (FLT_EPSILON < fabs(expect - actual)) {
+                printf("ERROR: image[%d][%d] is %f, should be %f\n", i, j, actual, expect);
+                testStatus = 1;
+            }
+        }
+    }
+
+
+    psFree(myReadout);
+    psFree(tmpImage2);
+    psFree(tmpImage3);
+    psFree(tmpImage4);
+    psFree(stat);
+    psFree(list);
+
+    printFooter(stdout, "pmSubtractBias", "Row Overscans", true);
+    return(testStatus);
+}
+
+int test03( void )
+{
+    int testStatus = 0;
+
+    testStatus |= doSubtractFullOverscanRows(1, 1);
+    testStatus |= doSubtractFullOverscanRows(1, NUM_ROWS);
+    testStatus |= doSubtractFullOverscanRows(NUM_COLS, 1);
+    testStatus |= doSubtractFullOverscanRows(NUM_COLS, NUM_ROWS);
+
+    return(testStatus);
+}
Index: /branches/rel3/psModules/test/verified/tst_pmFlatField.stderr
===================================================================
--- /branches/rel3/psModules/test/verified/tst_pmFlatField.stderr	(revision 2163)
+++ /branches/rel3/psModules/test/verified/tst_pmFlatField.stderr	(revision 2163)
@@ -0,0 +1,33 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: Test Point Driver{pmFlatField}                             *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psModule.src.pmFlatField
+    Null not allowed for flat readout.
+<DATE><TIME>|<HOST>|E|psModule.src.pmFlatField
+    Null not allowed for input image.
+<DATE><TIME>|<HOST>|E|psModule.src.pmFlatField
+    Null not allowed for flat image.
+<DATE><TIME>|<HOST>|E|psModule.src.pmFlatField
+    Input image size exceeds that of flat image: (3, 3) vs (2, 2)
+<DATE><TIME>|<HOST>|E|psModule.src.pmFlatField
+    Input image mask size exceeds that of flat image: (4, 4) vs (3, 3)
+<DATE><TIME>|<HOST>|E|psModule.src.pmFlatField
+    Total offset >= flat image size: (50, 50) vs (3, 3)
+<DATE><TIME>|<HOST>|E|psModule.src.pmFlatField
+    Complex types not allowed for input image. Type: 2064
+<DATE><TIME>|<HOST>|E|psModule.src.pmFlatField
+    Complex types not allowed for flat image. Type: 2064
+<DATE><TIME>|<HOST>|E|psModule.src.pmFlatField
+    Input and flat image types differ: (1032 vs 1028)
+<DATE><TIME>|<HOST>|E|psModule.src.pmFlatField
+    Mask must be PS_TYPE_MASK type. Type: 1028
+<DATE><TIME>|<HOST>|E|psLib.sysUtils.psFree
+    Block 1, allocated at psImage.c:<LINENO>, freed multiple times at tst_pmFlatField.c:<LINENO>.
+<DATE><TIME>|<HOST>|E|psLib.sysUtils.psFree
+    Block 5, allocated at psImage.c:<LINENO>, freed multiple times at tst_pmFlatField.c:<LINENO>.
+
+---> TESTPOINT PASSED (Test Point Driver{pmFlatField} | tst_pmFlatField.c)
+
Index: /branches/rel3/psModules/test/verified/tst_pmFlatField.stdout
===================================================================
--- /branches/rel3/psModules/test/verified/tst_pmFlatField.stdout	(revision 2163)
+++ /branches/rel3/psModules/test/verified/tst_pmFlatField.stdout	(revision 2163)
@@ -0,0 +1,221 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test A - Divide input image by flat image}     *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Input image:
+6.000000 6.000000 6.000000 
+6.000000 6.000000 6.000000 
+6.000000 6.000000 6.000000 
+
+Flat image:
+2.000000 2.000000 2.000000 
+2.000000 2.000000 2.000000 
+2.000000 2.000000 2.000000 
+
+Resulting image:
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+
+
+---> TESTPOINT PASSED (pmFlatField{Test A - Divide input image by flat image} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test B - Mask flat image data}                 *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Input image:
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+
+Flat image:
+0.000000 0.000000 0.000000 
+0.000000 0.000000 0.000000 
+0.000000 0.000000 0.000000 
+
+Resulting mask:
+8 8 8 
+8 8 8 
+8 8 8 
+
+
+---> TESTPOINT PASSED (pmFlatField{Test B - Mask flat image data} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test C - Mask flat image data starting with non-null mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+Input image:
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+3.000000 3.000000 3.000000 
+
+Flat image:
+0.000000 0.000000 0.000000 
+0.000000 0.000000 0.000000 
+1.000000 0.000000 0.000000 
+
+Resulting mask:
+8 8 8 
+8 8 8 
+0 8 8 
+
+
+---> TESTPOINT PASSED (pmFlatField{Test C - Mask flat image data starting with non-null mask} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test D - Attempt to use null flat readout}     *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null not allowed for flat readout                          *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test D - Attempt to use null flat readout} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test E - Attempt to use null input image}      *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null not allowed for input image                           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test E - Attempt to use null input image} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test F - Attempt tp use null flat image}       *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Null not allowed for flat image                            *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test F - Attempt tp use null flat image} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test G - Attempt to use input image bigger than flat image} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Input image size exceeds that of flat image                *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test G - Attempt to use input image bigger than flat image} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test H - Attempt to use input image mask bigger than flat image} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Input image mask size exceeds that of flat image           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test H - Attempt to use input image mask bigger than flat image} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test I - Attempt to use offset greater than input image} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Total offset >= input image size                           *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test I - Attempt to use offset greater than input image} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test J - Attempt to use complex input image}   *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Complex types not allowed for input image                  *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test J - Attempt to use complex input image} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test K - Attempt to use complex flat image}    *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Complex types not allowed for flat image                   *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test K - Attempt to use complex flat image} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test L - Attempt to use non-equal input and flat image types} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Input and flat image types differ                          *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test L - Attempt to use non-equal input and flat image types} | tst_pmFlatField.c)
+
+
+
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmFlatField.c                                          *
+*            TestPoint: pmFlatField{Test M - Attempt to use non-mask type mask image} *
+*             TestType: Negative                                                   *
+*    ExpectedErrorText: Mask must be PS_TYPE_MASK type                             *
+*  ExpectedStatusValue: 0                                                          *
+\**********************************************************************************/
+
+
+---> TESTPOINT PASSED (pmFlatField{Test M - Attempt to use non-mask type mask image} | tst_pmFlatField.c)
+
+
+
+
Index: /branches/rel3/psModules/test/verified/tst_pmMaskBadPixels.stderr
===================================================================
--- /branches/rel3/psModules/test/verified/tst_pmMaskBadPixels.stderr	(revision 2163)
+++ /branches/rel3/psModules/test/verified/tst_pmMaskBadPixels.stderr	(revision 2163)
@@ -0,0 +1,133 @@
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Create mask based on maskVal argument} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psLib.sysUtils.psFree
+    Block 1, allocated at psImage.c:<LINENO>, freed multiple times at tst_pmMaskBadPixels.c:<LINENO>.
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Create mask based on maskVal argument} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Create mask based on saturation argument} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psLib.sysUtils.psFree
+    Block 1, allocated at psImage.c:<LINENO>, freed multiple times at tst_pmMaskBadPixels.c:<LINENO>.
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Create mask based on saturation argument} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Create mask based on growVal and grow argum *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psLib.sysUtils.psFree
+    Block 1, allocated at psImage.c:<LINENO>, freed multiple times at tst_pmMaskBadPixels.c:<LINENO>.
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Create mask based on growVal and grow arguments} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Auto create mask based on maskVal argument} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psLib.sysUtils.psFree
+    Block 1, allocated at psImage.c:<LINENO>, freed multiple times at tst_pmMaskBadPixels.c:<LINENO>.
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Auto create mask based on maskVal argument} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Attempt to use null mask} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psModule.src.pmMaskBadPixels
+    Null not allowed for mask image.
+<DATE><TIME>|<HOST>|E|psLib.sysUtils.psFree
+    Block 1, allocated at psImage.c:<LINENO>, freed multiple times at tst_pmMaskBadPixels.c:<LINENO>.
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Attempt to use null mask} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Attempt tp use null input image} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psModule.src.pmMaskBadPixels
+    Null not allowed for input image.
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Attempt tp use null input image} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Attempt to use input image bigger than mask *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psModule.src.pmMaskBadPixels
+    Input image size exceeds that of mask image: (60, 60) vs (50, 50)
+<DATE><TIME>|<HOST>|E|psLib.sysUtils.psFree
+    Block 1, allocated at psImage.c:<LINENO>, freed multiple times at tst_pmMaskBadPixels.c:<LINENO>.
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Attempt to use input image bigger than mask} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Attempt to use input image mask bigger than *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psModule.src.pmMaskBadPixels
+    Input image mask size exceeds that of mask image: (60, 60) vs (50, 50)
+<DATE><TIME>|<HOST>|E|psLib.sysUtils.psFree
+    Block 1, allocated at psImage.c:<LINENO>, freed multiple times at tst_pmMaskBadPixels.c:<LINENO>.
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Attempt to use input image mask bigger than mask} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Attempt to use offset greater than input im *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psModule.src.pmMaskBadPixels
+    Total offset >= mask image: (150, 150) vs (50, 50)
+<DATE><TIME>|<HOST>|E|psLib.sysUtils.psFree
+    Block 1, allocated at psImage.c:<LINENO>, freed multiple times at tst_pmMaskBadPixels.c:<LINENO>.
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Attempt to use offset greater than input image} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Attempt to use complex input image} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psModule.src.pmMaskBadPixels
+    Complex types not allowed for input image. Type: 2064
+<DATE><TIME>|<HOST>|E|psLib.sysUtils.psFree
+    Block 1, allocated at psImage.c:<LINENO>, freed multiple times at tst_pmMaskBadPixels.c:<LINENO>.
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Attempt to use complex input image} | tst_pmMaskBadPixels.c)
+
+/***************************** TESTPOINT ******************************************\
+*             TestFile: tst_pmMaskBadPixels.c                                      *
+*            TestPoint: Test Point Driver{pmMaskBadPixels - Attempt to use non-mask type mask image} *
+*             TestType: Positive                                                   *
+\**********************************************************************************/
+
+<DATE><TIME>|<HOST>|E|psModule.src.pmMaskBadPixels
+    Mask must be PS_TYPE_MASK type. Type: 1032
+<DATE><TIME>|<HOST>|E|psLib.sysUtils.psFree
+    Block 1, allocated at psImage.c:<LINENO>, freed multiple times at tst_pmMaskBadPixels.c:<LINENO>.
+
+---> TESTPOINT PASSED (Test Point Driver{pmMaskBadPixels - Attempt to use non-mask type mask image} | tst_pmMaskBadPixels.c)
+
Index: /branches/rel3/psModules/test/verified/tst_pmMaskBadPixels.stdout
===================================================================
--- /branches/rel3/psModules/test/verified/tst_pmMaskBadPixels.stdout	(revision 2163)
+++ /branches/rel3/psModules/test/verified/tst_pmMaskBadPixels.stdout	(revision 2163)
@@ -0,0 +1,416 @@
+Data mask:
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000010000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+
+Resulting mask:
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000010000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+
+Data mask:
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+
+Resulting mask:
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+44444444444444444444444444444444444444444444444444
+
+Data mask:
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000010000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00010000000000000000000000000000000000000000001000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+
+Resulting mask:
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000011111110000000000000000000000
+00000000000000000001111111111100000000000000000000
+00000000000000000011111111111110000000000000000000
+00000000000000000111111111111111000000000000000000
+00000000000000001111111111111111100000000000000000
+00000000000000011111111111111111110000000000000000
+00000000000000011111111111111111110000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000011111111111111111110000000000000000
+00000000000000011111111111111111110000000000000000
+00000000000000001111111111111111100000000000000000
+00000000000000000111111111111111000000000000000000
+00000000000000000011111111111110000000000000000000
+00000000000000000001111111111100000000000000000000
+11111110000000000000011111110000000000000001111111
+11111111100000000000000000000000000000000111111111
+11111111110000000000000000000000000000001111111111
+11111111111000000000000000000000000000011111111111
+11111111111100000000000000000000000000111111111111
+11111111111110000000000000000000000001111111111111
+11111111111110000000000000000000000001111111111111
+11111111111111000000000000000000000011111111111111
+11111111111111000000000000000000000011111111111111
+11111111111111000000000000000000000011111111111111
+11111111111111000000000000000000000011111111111111
+11111111111111000000000000000000000011111111111111
+11111111111111000000000000000000000011111111111111
+11111111111111000000000000000000000011111111111111
+11111111111110000000000000000000000001111111111111
+
+Data mask:
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000010000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+
+Resulting mask:
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000011111110000000000000000000000
+00000000000000000001111111111100000000000000000000
+00000000000000000011111111111110000000000000000000
+00000000000000000111111111111111000000000000000000
+00000000000000001111111111111111100000000000000000
+00000000000000011111111111111111110000000000000000
+00000000000000011111111111111111110000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000111111111111111111111000000000000000
+00000000000000011111111111111111110000000000000000
+00000000000000011111111111111111110000000000000000
+00000000000000001111111111111111100000000000000000
+00000000000000000111111111111111000000000000000000
+00000000000000000011111111111110000000000000000000
+00000000000000000001111111111100000000000000000000
+00000000000000000000011111110000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000
+
